Active Directory en PHP
Active Directory, een term die iedere ITer of (systeem)beheerder een warm gevoel geeft! Wat is precies Active Directory dan? En heeft PHP hiermee te maken? Allemaal vragen waarin ik in deze tutorial antwoord op ga geven! Inhoud: - Wat betekend de term Active Directory en wat houdt het in. - Active Directory en het LDAP protocol. - PHP en LDAP plus verschillende mogelijkheden. - Verbinding maken met Active Directory middels het LDAP protocol. - Authenticeren via Active Directory. - Data ophalen / wegschrijven. - Gebruikermanagement (deel 1) Ik hoop dat je deze tutorial kan waarderen en de door mij gegeven voorbeelden kan gebruiken bij het realiseren van diversen applicaties. Code snippets De code snippets zijn expres niet Object Georienteerd, zodat ‘normale’ phpers de code ook kunnen begrijpen. Voor de mensen die Object Georienteerd programmeren komt er een hoofdstuk met library’s zodat ze daar hun hart kunnen ophalen. Op de code rust geen copyright (tenzij anders aangegeven), maar ik zou het leuk vinden als je mijn naam zou noemen. Tot slot, Vragen en/of opmerkingen zijn welkom mits het specifiek over deze tutorial gaat. Wanneer dit niet het geval is graag een nieuw topic maken in het daarvoor bestemde forum onderdeel. Wanneer je nieuw bent en graag wil weten hoe je iets op PHPhulp zet kan je deze tutorial volgen: klik. Veel leesplezier! Niels Kieviet.
Wat is Active Directory en wat houd het in?
Active Directory werd geïntroduceerd bij het verschijnen van Windows server 2000. Ook in zijn opvolger, Windows server 2003 is Active Directory geïmplementeerd. Op moment van schrijven bestaat Windows server 2008 al en ook daarin is Active Directory verreweg het belangrijkste onderdeel van dit netwerkbesturingssysteem.
Beveiliging:
Een netwerk heeft vooral de taak diensten te verlenen aan een gebruiker. Denk hierbij aan data sharing enzovoorts. Daarnaast speelt beveiliging een grote rol en is één van de belangrijkste bestaandsgronden voor client / server netwerken. In dit artikel twee soorten beveiliging:
- Verificatie
- Autorisatie
Verificatie en autorisatie zijn begrippen waar je ook in het dagelijkse leven mee geconfronteerd wordt. Als je bijvoorbeeld in een vliegtuig stapt, moet je daarvoor toestemming hebben: Autorisatie. Voor het vertrek moet je kunnen aantonen dat je op je eigen ticket reist en niet op die van iemand anders: Verificatie.
Verificatie:
Verificatie wordt gebruikt als toegangsbeveiliging tot het netwerk. Van jij als gebruiker worden bepaalde gegevens op het netwerk bewaard in een zogeheten user-account. Voor de verificatie zijn dat onder andere je gebruikersnaam en wachtwoord.
Autorisatie:
Autorisatie wordt gebruikt als toegangsbeveiliging voor een netwerk object dat aan jouw als gebruiker beschikbaar is gesteld. Elk netwerk object is voorzien van een ACL (Access Controll List). In de ACL zijn de toegangspermissies per netwerk object vastgesteld. De toegang via de ACL’s wordt geregeld via SID’s (Security Identifier) Een SID is een unieke waarde van je gebruikersaccount. (Bij het creëren van een account wordt een SID toegekend) Een SID met de daarbijbehorende toegangspermisies heet een ACE (Access Controll Entry). Dat betekend dus dat er in een ACL verschillende ACE’s kunnen voorkomen. Kortom via de autorisatie wordt dus geregeld of en zoja hoe jij als geverifieerde gebruiker van de netwerk objecten gebruik mag maken.
Structuur van een Active Directory server:
Een Active Directory server kan onder andere de volgende attributen bevatten:
- Domeinen
- Sites
- Trees
- Forests
- Trusts
Deze bovenstaande attributen hieronder breder uitgewerkt:
Domeinen:
Een domein is een verzameling gebruikers en computers met een gemeenschappelijk beveiligingsbeleid. Een domein wordt dan ook als een éénheid beheerd. Even een weetje voor je verder gaat:
Onder Windows NT4 Server was het gebruikelijk dat de geografische spreiding van een organisatie model stond voor het netwerk. Per locatie was er dus een domein. Het beheer was dus min of meer gedecentraliseerd. Via ingewikkelde modellen en methodes werden de verschillende domeinen in één structuur ondergebracht. Je zal je hoogstwaarschijnlijk afvragen waarom dit? En niet alles centraal? De belangrijkste reden om verschillende domeinen te hanteren was de beperkte capaciteit. Officeel konden er ‘maar’ 100.000 gebruikers in een domein worden opgenomen. Echter, in de praktijk bleek dat er boven ongeveer de 20.000 er al problemen ontstonden. Grote ondernemingen waren dus genoodzaakt het beheer gedecentraliseerd te organiseren. De capaciteit is vandaag de dag gelukkig geen probleem meer. Miljoenen gebruikers kunnen er nu in een domein worden opgenomen. (De grens is nog steeds niet ontdekt)
Sites:
Een site is een geografische eenheid, een locatie. Een domein is een logische eenheid van gebruikers en computers, een site een fysieke. Je kan je waarschijnlijk wel voorstellen dat een bedrijf één domein heeft waarbij de kantoren op twee verschillende locaties staan. In dat geval is het domein verspreid over twee sites. Omgekeerd is het mogelijk om direct na een bedrijfsovername twee domeinen op één locatie te hebben. Dan zijn er twee domeinen in één site.
Trees:
Een tree is niets anders dan een hiërarchische domeinstructuur. Dat is te verdelen in de volgende attributen:
- Root domein
- Parent domein
- Child domein
De domeinnamen in een tree vormen een Contiguous namespace, een aangrenzende naamruimte. Behalve het Root Domain heeft elk ander domein een eigen naamdeel, gevolgd door de naam van het Parent domain.
Forests:
Elke organisatie moet zich kunnen beschermen tegen de buitenwereld. In Active Directory bestaat de bescherming onder andere uit de verzameling user-accounts van alle bedrijfsdeelnemers. Ik heb al eerder verteld dat een domein kan worden beschouwd als de kleinste standaard beveiligingseenheid binnen een organisatie. Ik heb ook al verteld dat organisaties verschillende domeinen kunnen hebben, ondergebracht in één of meerdere trees. Een forest kan worden beschouwd als de grootste beveiligingseenheid binnen Active Directory. Een forest bakent de beveiliging van de gehele organisatie af. Een forest kan bestaan uit één of meerdere domeinen. De belangrijkste eigenschap van een forest is dat verschillende domeinen elkaar vertrouwen. Hierdoor kunnen alle bedrijfsonderdelen met elkaar samenwerken. Alles wat niet tot de forest behoort, wordt dus niet vertrouwd en kan geen toegang krijgen tot de netwerkobjecten.
Trusts:
Een vertrouwensrelatie tussen domeinen wordt een Trust relationship of korter Trust genoemd. Via een trust wordt het mogelijk dat gebruikers uit het ene domein kunnen beschikken over bronnen uit het andere domein. Voorbeeld: Wanneer je een printer uit een ander domein wilt gebruiken moet er tussen het domein waar je nu in zit en het andere domein een Trust relationship bestaan.
Active Directory zelf:
De gegevens van alle netwerkobjecten moeten ergens op het netwerk worden opgeslagen. Wanneer dit niet gebeurd kan er bijvoorbeeld niet worden geverifieerd of geautoriseerd en werkt de netwerkbeveiliging niet. Al deze gegevens worden bewaard in het bestand NTDS.DIT. NTDS is een afkorting van New Technology Directory Service. DIT is een afkorting van Data Information Table. Het bestand NTDS.DIT wordt dus Active Directory genoemd. Een Windows server waarop Active Directory is geïnstalleerd, heet een Domain Controller. Active Directory NTDS.DIT is dus een databasebestand. Het bestand wordt bewerkt met een databaseprogamma. In Windows server wordt dat gedaan door het databaseprogramma: directories. Het databaseprogramma plus Active Directory worden samen de Directory Service genoemd.
Active Directory is zo ontworpen dat het naadloos aansluit bij de geldende Internet-standaarden. Zo heeft Active Directory onder ander het Domain Name System (DNS) nodig om goed te kunnen functioneren. Voor deze tutorial is het voldoende als je weet dat DNS ervoor zorgt dat een computer in het netwerk via zijn naam kan worden opgespoord. (Het is dus noodzakelijk dat computernamen uniek zijn)
De Global Catalog:
In uitgebreide domeinstructuren kost het erg veel tijd en netwerkcapaciteit om informatie uit een domein op te halen. (Denk aan een domein wat in een andere tree van een forest ligt) Daarom gebruikt Active Directory de Global Catalog. Een Global Catalog wordt op één of meerdere Domain Controllers bewaard. Die Domain Controllers zijn dan Global Catalog Servers (GCS). Per definitie is de eerste Domain Controller van het eerste domein van de eerste tree in een forest een GCS. De Global Catalog is een database waarin de volgende attributen worden opgeslagen:
- Van alle objecten uit het eigen domein worden de eigenschappen bijgehouden.
- Van alle objecten uit de overige domeinen wordt een deel van de eigenschappen bijgehouden.
Van gebruikers uit het eigen domein worden alle eigenschappen bijgehouden. Bij de gebruikers uit de overige domeinen is dat alleen de gebruikersnaam, de voornaam, de achternaam en het wachtwoord. Via een replicatieproces wordt de Global Catalog op de Global Catalog Servers gelijk gehouden.
Objectgeoriënteerd:
Active Directory werkt objectgeoriënteerd. Objecten moeten gedefinieerd zijn. Dat definiëren begint bij het Active Directory schema. Het Active Directory Schema is een verzameling definities. In het Schema bestaan twee soorten definities:
- Attributen.
- Objectklassen.
In een attribuut wordt een kenmerk gedefinieerd. Elk attribuut wordt maar één keer gedefinieerd. Daarbij is ook het type van de informatie vastgelegd.
Een objectklasse bestaat uit een aantal attributen die ook in het Schema zijn gedefinieerd. Een objectklasse werkt als een sjabloon. Door een instantie van een objectklasse te creëren, wordt een daadwerkelijk object gemaakt. Dat object erft de attributen uit de desbetreffende objectklasse. De attributen van het object bevatten de informatie die het object beschrijven: De attribuutwaarden. Wanneer je met Window Server werkt kan je ze terug zien in het propertie-venster van het object als de object-properties: De eigenschappen in het eigenschappen venster.
Elk object in Active Directory wordt gekarakteriseerd via zijn GUID. GUID is een afkorting van Global Unique Identifier. De GUID is een nummer van 128 bits. Elk object krijgt bij het creëren ervan een GUID. Het zoeken naar objecten in Active Directory gaat met behulp van GUIDs.
Standaard objectklassen:
Nu je weet hoe objecten in Active Directory tot stand komen, bespreek ik de belangrijkste standaard ingebouwde objectklassen.
Users:
Voor elke gebruiker in Active Directory moet een user-object worden aangemaakt door een instantie te creëren van de betreffende objectklasse. Bij dat aanmaken moet je tenminste de User logon name van het (voorlopige) Password invoeren. De User logon name wordt ook wel de accountnaam / gebruikersnaam genoemd. Later kan je nog een groot aantal andere eigenschappen toekennen. Een aantal daarvan behandel ik in een aantal hoofdstukken hierna. Een gebruiker is een Security principal en kan dus via zijn SID voorkomen in ACE’s van de ACL’s van netwerkobjecten zoals ik al eerder verteld heb.
Computers:
Voor elke computer die lid wordt van een domein wordt een computer-account aangemaakt. Je creëert daarbij een instantie van de desbetreffende objectklasse. Een computer moet een unieke Computer name hebben. Ook een computer is een Security principal zodat deze een eigen SID heeft.
Groepen:
Een groep maak je door een instantie te creëren van de objectklasse Group. In een groepobject breng je gebruikers-accounts en/of computer-accounts onder in een logische eenheid. In veel gevallen kan een groep zelf ondergebracht worden in andere groepen. Van groepen bestaan twee categorieën. De Security groups zijn Security principals en bezitten een eigen SID. En Distribution groups zijn dat niet. Groepen hebben betrekking op een scope, een reikwijdte. Op Domain Controllers kunnen de volgende soorten groepen voorkomen:
- Universal groups.
- Global groups.
- Domain local groups.
In één van de volgende hoofstukken kan je hier mee over lezen.
Organizational Units:
Een Organizational Unit (OU) is een containerobject. Een Organizational Unit herbergt objecten uit het eigen domein. Een Organizational Unit kan de volgende objecten bevatten:
- Users.
- Computers.
- Gedeelde bronnen (Schijven, folders en printers).
- Applicaties.
- Andere Organizational Units.
Organizational Units zijn de kleinste eenheden waarvan je beheertaken kan delegeren. Op een Organizational Unit kan je Group Policies toepassen. Met Organizational Units kan je binnen een domein een structuur opzetten die lijkt op een organisatorische structuur van een bedrijf. Daardoor wordt het beheer realistischer en daarmee eenvoudiger. Organizational Units zijn geen Security principals. Voor meer informatie over Group Policies: klik
Installatie:
Deze tutorial legt niet uit hoe je precies een Active Directory server installeerd en configureerd. Wanneer je dit wel wilt weten kan je het beste één van deze tutorials volgen: WS 2003, WS 2008 (Let op, deze tutorial verwacht dat je al een windows server hebt geïnstalleerd.)
LET OP: Wanneer je gebruik wilt maken van de ldap_* functies moet de LDAP extensie worden geïmporteerd.
Installatie / Configuratie Windows: klik
Installatie / Configuratie Linux: klik
Zo ben je al weer aan het einde van dit hoofstuk gekomen. Ik hoop dat je er iets van geleerd hebt, en dat je een beeld hebt van wat Active Directory nu precies inhoud.
In het volgende hoofdstuk wil ik gaan uitleggen wat nu precies het LDAP protocol is en wat dat precies met Active Directory te maken heeft.
Voor mensen die nog meer willen weten over Active Directory en Windows server raad ik het boek 'Smets netwerken' van Jan Smets aan. Bepaalde teksten van de bovenstaande informatie zijn ook uit zijn boek.
LDAP protocol plus verschillende mogelijkheden.
LDAP staat voor ‘Lightweight Access Protocol’ en is een netwerkprotocol dat beschrijft hoe gegevens uit directoryservices (Active Directory in dit geval) benaderd moeten worden. Dit kan op verschillende manieren, over bijvoorbeeld TCP/IP. Een directory is in dit verband informatie die op een hiërarchische manier, gegroepeerd naar een bepaald attribuut, is opgeslagen.
Het ontstaan van het LDAP protocol:
Eerst een voorbeeld van een Directory. Denk aan een telefoonboek waarin telefoonnummer en addressen van personen per bedrijf worden opgeslagen. Een directorynaam komt overeen met de bedrijfsnaam. Iedere directory bevat dan alle personen binnen dat bedrijf als objecten, met contactgegevens zoals telefoonnummer en e-mailadres als attributen.
Het bovenstaande voorbeeld schets de oorsprong van het LDAP, namelijk de telecommunicatie. Vanuit deze wereld zijn de telefoondirectory’s het domein van de computernetwerken binnengekomen. Om de nu elektronische telefoondirectory’s beter te kunnen beheren is door International Telecommunication Union (ITU) de zogenaamde X.500 standaard ontwikkeld. Een onderdeel van deze standaard is het Directory Access Protocol (DAP). Via dit protocol werden achterliggende directory’s op een gecontroleerde en gestructureerde manier toegankelijk.
De omschrijving van de X.500 standaarden waren (heel) precies en daarom ook erg omvangrijk. Vandaar dat er betrekkelijk weinig implementaties van deze standaarden zijn gemaakt. De implementaties die er wel waren, behoefden echter veel rekenkracht. Er onstond dan ook de vraag naar een lichtere implementatie van de X-500 standaarden. Het Lightweight Access Protocol (LDAP) zoals dat hierboven is omschreven werd ontwikkeld!
De huidige versie (op moment van spreken) is LDAPv3. Deze heeft minder overhead dan zijn zwaardere voorganger DAP. Zo kent de huidige versie slechts negen basis operaties, en kende de oorspronkelijke versie van LDAP zelfs geen beveiligingsopties.
Kort samengevat dus, het LDAP protocol is een tussenlaag. Op die tussenlaag is Active Directory gebouwd. En omdat PHP met LDAP kan communiceren betekend het dat PHP middels het LDAP protocol kan gaan communiceren met Active Directory.
Probeer die communicatie methode te onthouden. In de volgende artikelen snap je dan de gedachtengang.
Nu je weet wat Active Directory en LDAP inhoud wordt het tijd om PHP erbij te gaan betrekken. Wat dat is natuurlijk de grote vraag. Wat kan je precies allemaal met PHP en het LDAP protocol.
Zonder al te diep in te gaan op PHP en LDAP geef ik je een lijstje met diversen mogelijkheden van PHP en Active Directory middels het LDAP protocol.
- Authenticeren van gebruikers
- Groep management
- Gebruiker management
- Contact management
- Exchange mail management
Dit lijstje kan met veel meer mogelijkheden worden uitgebreid maar dat heeft geen zin.
In het volgende hoofdstuk zal worden uitgelegd hoe je nu precies een connectie tot stand brengt. Als je nog vragen hebt over het bovenstaande hoor ik het graag!
Connecteren met Active Directory
Voordat je een connectie gaat opzetten zijn er een aantal zaken die je moet weten voordat je verder gaat. Deze zijn hieronder weergegeven:
Hostname van je server:
De hostname kan op drie verschillende manier worden gedefinieerd:
- Naam van je server
- Webadres
- Intern of extern IPadres
Poortnummer:
Nu de hostname is gedefinieerd is alleen het poortnummer nog van belang. Standaard draait een LDAP server op poort 389, vandaar dat het poortnummer ook optioneel is. Maar omdat we niets willen uitsluiten definiëren we ook het poortnummer. Wanneer je LDAP over SSL draait is het standaard poortnummer 636.
Bestudeer onderstaand code snippet om te zien hoe het bovenstaande er in PHP uit ziet:
<?php
// Even wat configuratie
$config = array(
'hostname' => 'nielskieviet.local',
'portnumber' => 389,
'sslPortnumber' => 636
);
/**
* Verbinding zonder SSL
*/
$ldapConnection = ldap_connect($config['hostname'], $config['portnumber']); // 'Portnumber' is optioneel maar voor de zekerheid gewoon configureren.
if (!$ldapConnection) {
// Er is een fout opgetreden bij het connecteren van de LDAP server
trigger_error('Er is een fout opgetreden bij het connecteren van de LDAP server. Error: `' .ldap_error($ldapConnection). '`');
exit;
}
/**
* Verbinding met SSL
*/
$sslLdapConnection = ldap_connect('ldaps://' .$config['hostname'], $config['sslPortnumber']); // 'Portnumber' verschilt, plus ldaps:// is toegevoegd
if (!$sslLdapConnection) {
// Er is een fout opgetreden bij het connecteren van de LDAP server
trigger_error('Er is een fout opgetreden bij het connecteren van de LDAP server. Error: `' .ldap_error($sslLdapConnection). '`');
exit;
}
?>
Zoals ik al vertelde, zeer éénvoudig. Er is echter één maar bij. Wanneer je OpenLDAP versie 2 draait retourneert "ldap_connect" altijd een resource. Het if - statement is dan overbodig. (Je krijgt wel een error, maar je kan dus niet specifiek een eigen foutmelding plaatsen, of je moet een eigen error handler gaan gebruiken)
Voordat je verder gaat is het belangrijk om je LDAP connectie juist te configureren. Dit omdat de configuratie bepaald welke functionaliteiten je wel of niet kunt gebruiken. Voor het configureren van je LDAP kan je de functie [php]ldap_set_option[/php] gebruiken. Zie ook onderstaand voorbeeld:
<?php
// Zoals al eerder verteld is versie 3 de meeste recente versie van LDAP, deze configureren
if (!ldap_set_option($ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3)) {
trigger_error('Protocol versie 3 kan niet worden geconfigureerd');
exit;
}
// Referenties
if (!ldap_set_option($ldapConnection, LDAP_OPT_REFERRALS, 0)) {
trigger_error('Referenties kunnen niet worden geconfigureerd');
exit;
}
?>
Wanneer je LDAP over SSL draait ben je verplicht om gebruik te maken van TLS. Dit is simpel aan te geven middels de volgende code:
<?php
// LDAP over SSL / LTS
if (!ldap_start_tls($ldapConnection)) {
trigger_error('LDAP over SSL kan niet worden ingeschakeld.');
exit;
}
?>
LET OP: Wanneer je gebruik maakt van de TLS functionaliteit is LDAP versie 3 vereist!
Zo ben je alweer aan het eind gekomen van dit hoofdstuk. Ik hoop dat je er wat van geleerd hebt, en wanneer je vragen en / of problemen hebt met bovenstaande informatie, schroom je niet om ze te stellen.
Authenticatie en Active Directory
Voor het authenticeren met Active Directory zijn een aantal zaken van belang. Deze zijn hieronder weergeven:
- Connectie met de Active Directory server middels het LDAP protocol.
- Gebruikersnaam en wachtwoord.
- Domein gegevens.
Elke authenticatie, op welke manier dan ook, verwacht een identity (identiteit) en een credential (referenties). Wanneer je gaat authenticeren met Active Directory is dit niet anders. Echter heb je bij deze authenticatie ook nog wat extra informatie nodig, genaamd "account suffix". De "account suffix" is je volledige domeinnaam, dus met je domein extensie. Voorbeeld: "nielskieviet.local". Vind je domeinnaam als volgt:
"Start" > rechtermuisknop op "My Computer" > "properties" > tabblad "Computer Name" > "domain".Zoals het woord al zegt komt de 'account suffix' achter je accountnaam (gebruikersnaam) te staan. Dit is nodig om te verifiëren bij welk domein het account geauthenticeerd moet worden.
<?php
/**
* LET OP! Ik ga hier al vanuit dat de connectie is gelegd en dat de juiste instellingen
* zijn geconfigureerd! Lees het vorige artikel nogmaals om te kijken hoe er connectie
* kan worden gelegd en hoe de instellingen worden geconfigureerd.
*/
$config = array(
'username' => 'niels',
'password' => 'kieviet',
'accountSuffix' => '@nielskieviet.local'
);
if (!authenticate($ldapConnection, $config['username'], $config['password'], $config['accountSuffix'])) {
// Gebruiker is niet geauthenticeerd..
trigger_error('Gebruiker kon niet worden geauthenticeerd. Error: ' .ldap_error($ldapConnection));
exit;
}
/**
* Functie voor het authenticeren van een gebruiker
*
* @param Mixed $ldapConnection
* @param String $username
* @param String $password
* @param String $accountSuffix
*/
function authenticate($ldapConnection, $username, $password, $accountSuffix)
{
return (false !== ldap_bind($ldapConnection, $username . $accountSuffix, $password));
}
?>
Zoals je ziet, is het zeer eenvoudig, er is gebruik gemaakt van de functie "authenticate" die een "ldap_bind" tot stand probeert te brengen, aan de hand van je gebruikersnaam, "accountsuffix" en je wachtwoord. Aan de hand van het resultaat van de poging wordt er een boolean geretourneerd, wat kan leiden tot het verder uitvoeren van de applicatie, of tot het tonen van de foutmelding dat de gebruiker niet kon worden geauthenticeerd.
Wat ook mogelijk is, is het genereren van een Single Sign On (SSO) middels het Kerberos protocol. Aangezien dat zelf al een hoofdstuk waard is wordt dit in een later stadium behandeld.
Tot slot, er zijn nog een aantal zaken waarmee je rekening moet houden wanneer je dit gebruikt:
- Zorg ervoor dat de LDAP connectie aanwezig, en juist geconfigureerd is. (Zie ook het vorige hoofdstuk)
- Dit script zorgt niet voor een formulier of de validatie daarvan, zorg daar dus zelf voor.
Het volgende hoofdstuk wordt een stuk spannender! Daarin wordt uitgelegd hoe je nu precies data kan ophalen en kan wegschrijven.
Gebruikersmanagement (1)
Hieronder genoteerd wat in dit artikel qua gebruikersmanagement behandeld gaat worden:
- Het realiseren van een export van alle gebruiker die in Active Directory zijn opgeslagen.
- Het creëren van een nieuwe gebruiker.
- Het toevoegen / wijzigen van gebruikers attributen.
- Het samenstellen van een gebruiker informatie schema.
Wanneer ik alles in één hoofdstuk zou plaatsen zou het onoverzichtelijk worden, vandaar dat het hoofdstuk "Gebruikersmanagement" een aantal (sub)delen heeft.
Het exporteren van gebruikers:
Het kan zo zijn dat je alle gebruikers die in Active Directory zitten wilt opvragen. Denk aan bijvoorbeeld een gebruikersoverzicht. Hieronder eerst een functie die dat mogelijk maakt waarna zal worden uitgelegd wat de functie nu precies doet en hoe het exporteren van de gebruikers tot stand komt.
<?php
function exportUsers($ldapConnection, $config = array())
{
$filter = '(&(objectClass=user)(samaccounttype=' .$config['samaccounttype']. ')(objectCategory=person)(cn=' .$config['search']. '))';
$fields = array(
'samaccountname',
'displayname'
);
$search = ldap_search($ldapConnection, $config['baseDn'], $filter, $fields);
if (!$search) {
trigger_error('Er is een fout opgetreden bij het zoeken in Active Directory. Error: ' .ldap_error($ldapConnection), E_USER_ERROR);
exit;
}
$entries = ldap_get_entries($ldapConnection, $search);
if (!$entries) {
trigger_error('Er is een fout opgetreden bij het ophalen van de gegevens uit Active Directory. Error: ' .ldap_error($ldapConnection), E_USER_ERROR);
exit;
}
$users = array();
for ($i = 0; $i < $entries['count']; $i++) {
if (false !== $config['includeDescription']) {
$users[] = array(
'name' => $entries[$i]['samaccountname'][0],
'description' => (isset($entries[$i]['displayname']) && !is_null($entries[$i]['displayname'][0])) ? $entries[$i]['displayname'][0] : $entries[$i]['samaccountname'][0]
);
}
else {
array_push($users, $entries[$i]['samaccountname'][0]);
}
}
if ($config['sort']) {
asort($users);
}
return $users;
}
?>
Er zijn een aantal zaken van belang voor het exporteren van alle gebruikers:
- Een connectie met de Active Directory server. (Let op, deze functie controleert niet of er daadwerkelijk een connectie aanwezig is)
- Een LDAP "binding" zoals die in het vorige hoofdstuk is besproken. (Ook voor dit punt geldt dat niet wordt gecontroleerd of er daadwerkelijk een LDAP "binding" aanwezig is)
Wanneer je niet meer precies weet hoe je een connectie opzet, of hoe je een gebruiker aan Active Directory "bind" (verbind) kan je het beste voorgaande artikelen (nogmaals) lezen.
Als tweede parameter wordt er een array met configuratie verwacht. Zo'n array kan er als volgt uit zien:
<?php
$schemaConfig = array(
'includeDescription' => false,
'search' => '*',
'sort' => true,
'baseDn' => 'DC=nielskieviet,DC=local',
'samaccounttype' => 805306368 // Standaard account type
);
?>
Alle waarden in de array zijn verplicht, Er wordt in de bovenstaande functie niet gecontroleerd of de waarden daadwerkelijk in de array zitten. Wanneer je de functie gaat gebruiken is het aan jezelf of je die controles nog toevoegt.
- includeDescription:
Wanneer je includeDescription op true zet retourneert de functie een twee-dimensionale array. Het retourneren van een associatieve array is ook mogelijk, maar dan moet je de for-loop in de functie aanpassen. (Zie onderstaande)
<?php
for ($i = 0; $i < $entries['count']; $i++) {
if (false !== $config['includeDescription']) {
// Associatieve array
$users[$entries[$i]['samaccountname'][0]] = (isset($entries[$i]['displayname']) && !is_null($entries[$i]['displayname'][0])) ? $entries[$i]['displayname'][0] : $entries[$i]['samaccountname'][0];
}
else {
array_push($users, $entries[$i]['samaccountname'][0]);
}
}
?>
Er wordt eerst gekeken of de "displayName" van de gebruiker niet leeg is. ("displayName" is de uitvoerige naam met informatie van de gebruiker), wanneer deze niet leeg is wordt die aan de array toegevoegd, en anders wordt de accountnaam / gebruikersnaam in de array geplaatst.
- Search:
De * betekend dat er geen criteria van toepassing is. Later in deze reeks met artikelen zal er verder uitleg komen en aan de hand van wat voorbeelden worden uitgelegd welke parameters je kan gebruiken.
- Sort:
De sort parameter is een boolean welke aangeeft of de resultaten van de zoekactie aan het eind nog alfabetisch moeten worden gesorteerd. Je kan het eventueel nog uitbreiden / aanpassen met de mogelijkheid tot het sorteren op andere volgorde methodes.
- baseDn:
De baseDn is je domeinnaam op dezelfde manier als de "account suffix" uit het vorige artikel. Voorbeeld: DC=nielskieviet,DC=local.
- samaccounttype:
In deze variabele moet het type account worden opgenomen. Je hebt de volgende "samaccountypes":
- 805306368 - Normaal account
- 805306369 - Vertrouwend werkstation
- 805306370 - Vertrouwend domein
- 268435456 - Globale security groep
- 536870912 - Lokale security groep
- 268435457 - Globale distributie groep
- 536870913 - Lokale distributie groep
Aangezien je voor het exporteren van alle gebruikers het accountype 'Normaal account (805306368)' nodig hebt, is die in de array opgenomen.
Het resultaat van export van de gebruikers zonder "includeDescription" kan er dan als volgt uit zien:
Array
(
[0] => Niels
[1] => Hendrik
)
Met "includeDescription" ziet een voorbeeld array er zo uit. (twee-dimensionale array)
Array
(
[0] => Array
(
[name] => Niels
[description] => Niels kieviet
)
[1] => Array
(
[name] => Hendrik
[description] => Hendrik kieviet
)
)
En een "includeDescription" met een associatieve array.
Array
(
[Niels] => Niels kieviet
[Hendrik] => Hendrik Kieviet
)
Nog een laatste opmerking, houdt er rekening mee dat tot en met PHP5.3 PHP niet meer dan 1000 resultaten op kan halen. Dit komt omdat PHP dan nog geen paged results ondersteund. In PHP 5.4 is dit probleem opgelost.
Ik hoop dat je er wat van geleerd hebt, en wanneer je vragen hebt.. Schroom je niet om ze te stellen!
Reacties
0