LDAP postavke
From LimeSurvey Manual
Općenito
Da biste mogli koristiti ovu funkciju, morate omogućiti LDAP podršku u datoteci config.php i konfigurirati LDAP parametre u datoteci config/ldap.php.
Omogućavanje LDAP-a u datoteci config.php
- $enableLdap: ako želite koristiti LDAP funkcije u LimeSurveyju, morate ovaj parametar postaviti na true (prema zadanim postavkama postavljen je na false):
'config'=>array( 'debug'=>0, 'debugsql'=>0, 'enableLdap'=>true, )
Definiranje LDAP poslužitelja
Prvo definirajte opcije povezivanja s LDAP poslužiteljem u datoteci "application/config/ldap.php". Za svaki poslužitelj dostupne su sljedeće opcije:
- $serverId: Cijeli broj koji identificira ovaj LDAP poslužitelj. Koristi se u definicijama upita za povezivanje poslužitelja s određenim upitom;
- $ldap_server[$serverId]['server']: IP adresa ili DNS naziv LDAP poslužitelja. Ako koristite SSL zaštićene veze (LDAPs ili LDAP+Start-TLS), ovaj naziv mora odgovarati CN-u certifikata poslužitelja (ili SubjectAlternativeName);
- $ldap_server[$serverId]['port']: TCP port na kojem LDAP poslužitelj sluša. To je obično 389 za LDAP i LDAP+Start-TLS te 636 za LDAPs;
- $ldap_server[$serverId]['protoversion']: Može biti 'ldapv2' ili 'ldapv3', ovisno o protokolu koji vaš poslužitelj podržava. 'ldapv3' je preferirani protokol. No ako želite koristiti šifrirane veze, imajte na umu da se LDAPs podržava u načinu 'ldapv2', dok je Start-TLS metoda šifriranja za 'ldapv3';
- $ldap_server[$serverId]['encrypt']: Definira korištenu metodu šifriranja. 'ldaps' je podržan za 'ldapv2' poslužitelje, a 'start-tls' za 'ldapv3' poslužitelje. Ključna riječ 'none' koristi se za LDAP komunikaciju u čistom tekstu;
- Ne zaboravite da za 'ldaps' ili 'start-tls' šifriranje web poslužitelj mora moći provjeriti certifikat LDAP poslužitelja. Stoga morate definirati svoje tijelo za izdavanje certifikata (Certificate Authority) u svojoj openldap biblioteci (na Linuxu se to obično radi u datoteci /etc/openldap/ldap.conf).
- $ldap_server[$serverId]['referrals']: Booleov parametar koji definira treba li pratiti preusmjeravanja (referrals) ili ne (za ActiveDirectory koristite false);
- $ldap_server[$serverId]['encoding']: Neobavezan parametar koji određuje kodiranje koje LDAP direktorij koristi za pohranu nizova znakova. Ovaj parametar obično ne trebate postavljati jer je zadano pretpostavljeno kodiranje 'utf-8' standardno kodiranje za LDAP direktorije. No ako koristite Active Directory i imate problema s uvozom znakova s dijakritičkim oznakama, pokušajte ovaj parametar postaviti na kodiranje koje se koristi u vašem području (na primjer 'cp850' za zapadnu Europu). Cjelovit popis podržanih kodiranja možete pronaći na padajućem izborniku "Set karaktera sadržaja datoteke" u sučelju Uvoz tokena iz CSV datoteke.
Zatim morate definirati koja je autentifikacija potrebna za pristup direktoriju. Ako je dopušten 'anonimni' pristup, NEMOJTE postavljati sljedeća dva parametra, a u suprotnom ih postavite prema potrebi:
- $ldap_server[$serverId]['binddn']: DN 'LDAP' korisnika kojem je dopušteno čitati direktorij;
- $ldap_server[$serverId]['bindpw']: Zaporka gore navedenog LDAP korisnika.
Ako trebate definirati dodatne LDAP poslužitelje, dodajte sljedeći redak kako biste povećali serverID i definirali nove parametre:
- $serverId++.
Definiranje upita u datoteci config/ldap.php
Oprez: kada je u jednom od ovih parametara potreban naziv ldap atributa, koristite samo mala slova: na primjer displayname, a NE displayName.
Pogledajte datoteku config/ldap.php jer sadrži primjere konfiguracije.
Jednostavni upiti
Počnimo s jednostavnim upitima. Ovi upiti filtriraju LDAP zapise samo na temelju njihovih vlastitih atributa i lokacije. Obično su dovoljni za upite prema ActiveDirectoryju.
- $query_id: je ID LDAP upita;
- $ldap_queries[$query_id]['ldapServerId']: Povezuje upit s određenim poslužiteljem;
- $ldap_queries[$query_id]['name']: Niz znakova koji opisuje upit. Prikazat će se u sučelju;
- $ldap_queries[$query_id]['userbase']: Korijenski DN koji se koristi za pretraživanje korisnika;
- $ldap_queries[$query_id]['userfilter']: Filter koji se koristi za odabir potencijalnih korisničkih zapisa. Mora biti u zagradama;
- $ldap_queries[$query_id]['userscope']: opseg LDAP pretraživanja korisnika ('base', 'one' ili 'sub');
- $ldap_queries[$query_id]['firstname_attr']: Ldap atribut koji će biti preslikan u polje Ime u zapisu tokena;
- $ldap_queries[$query_id]['lastname_attr']: Ldap atribut koji će biti preslikan u polje Prezime u zapisu tokena;
- $ldap_queries[$query_id]['email_attr']: Ldap atribut koji će biti preslikan u polje e-mail adrese u zapisu tokena.
Po želji možete dohvatiti dodatne informacije iz direktorija:
- $ldap_queries[$query_id]['token_attr']: Ldap atribut koji će biti preslikan u kôd tokena;
- $ldap_queries[$query_id]['language']: Ldap atribut koji će biti preslikan u kôd jezika korisnika;
- $ldap_queries[$query_id]['attr1']: Ldap atribut koji će biti preslikan u polje attribute_1;
- $ldap_queries[$query_id]['attr2']: Ldap atribut koji će biti preslikan u polje attribute_2.
Kombinirani upiti grupa s DN članovima
Pogledajmo sada kako definirati složeniji upit.
Sljedeći upiti koriste prvo LDAP pretraživanje koje traži po LDAP grupama. LDAP grupa je LDAP zapis koji sadrži reference na korisničke zapise u obliku:
- korisničkih ID-ova (na primjer posixGroups) ==> Pogledajte sljedeći odjeljak
- Ili korisničkih DN-ova (na primjer groupofnames i groupofuniquenames) ==> pogledajte u nastavku
Ovdje se bavimo grupama koje sadrže korisničke DN-ove:
- definirajte $query_id, $ldap_queries[$query_id]['ldapServerId'], $ldap_queries[$query_id]['name'] kako je objašnjeno gore.
Zatim definirajte parametre filtra grupa:
- $ldap_queries[$query_id]['groupbase']: Korijenski DN od kojeg želite započeti pretraživanje zapisa grupa;
- $ldap_queries[$query_id]['groupfilter']: LDAP filter koji će odabrati potencijalne zapise grupa;
- $ldap_queries[$query_id]['groupscope']: Opseg LDAP pretraživanja grupa ('one', 'base' ili 'sub');
- $ldap_queries[$query_id]['groupmemberattr']: Naziv LDAP atributa u zapisu grupe koji će sadržavati reference na korisničke zapise;
- $ldap_queries[$query_id]['groupmemberisdn']: TRUE.
U ovom trenutku sve je postavljeno da prvo LDAP pretraživanje pronađe korisnike koji odgovaraju odabranim grupama. No možete ograničiti koji će se od tih "kandidata za korisnike" odabrati primjenom dodatnog filtra na njih. To je, naravno, neobavezno:
- $ldap_queries[$query_id]['userbase']: Osnovni DN za LDAP pretraživanje korisnika (odabrat će se samo kandidati za korisnike koji odgovaraju ovoj bazi);
- $ldap_queries[$query_id]['userscope']: Opseg LDAP pretraživanja korisnika (odabrat će se samo kandidati za korisnike koji odgovaraju kombinaciji userbase+scope);
- $ldap_queries[$query_id]['userfilter']: Filter koji se primjenjuje na zapis svakog kandidata za korisnika (na njegove atribute) radi dodatnog odabira.
Kombinirani upiti grupa s UID članovima
Pogledajmo sada kako definirati kombinirani upit grupe kada su članovi grupe korisnički UID-ovi, a ne korisnički DN-ovi.
Kao i kod upita grupa s DN članovima, ovi upiti koriste prvo LDAP pretraživanje koje traži zapise LDAP grupa i dohvaća njihove članove. Te se vrijednosti članova zatim koriste u filtru pretraživanja korisnika za traženje odgovarajućih zapisa. Stoga je potrebno konfigurirati još jedan parametar koji definira atribut u korisničkom zapisu koji treba odgovarati UID-u člana pronađenom u grupama.
Pregledajmo potrebne parametre:
- definirajte $query_id, $ldap_queries[$query_id]['ldapServerId'], $ldap_queries[$query_id]['name'] kako je objašnjeno gore
Zatim definirajte parametre filtra grupa:
- $ldap_queries[$query_id]['groupbase']: Korijenski DN od kojeg želite započeti pretraživanje zapisa grupa;
- $ldap_queries[$query_id]['groupfilter']: LDAP filter koji će odabrati potencijalne zapise grupa;
- $ldap_queries[$query_id]['groupscope']: Opseg LDAP pretraživanja grupa ('one', 'base' ili 'sub');
- $ldap_queries[$query_id]['groupmemberattr']: Naziv LDAP atributa u zapisu grupe koji će sadržavati reference na korisničke zapise;
- $ldap_queries[$query_id]['groupmemberisdn']: FALSE;
- $ldap_queries[$query_id]['useridattr']: naziv korisničkog atributa koji mora odgovarati UID-u pronađenom među članovima grupe.
U ovom trenutku sve je postavljeno da prvo LDAP pretraživanje pronađe UID-ove korisnika koji odgovaraju odabranim grupama, a filtar pretraživanja korisnika bit će automatski popunjen.
No možete ograničiti koji će se od tih 'kandidata za korisnike' odabrati dopunjavanjem automatskog korisničkog filtra izračunatog iz UID-ova članova. To je, naravno, neobavezno:
- $ldap_queries[$query_id]['userbase']: Osnovni DN za LDAP pretraživanje korisnika (odabrat će se samo kandidati za korisnike koji odgovaraju ovoj bazi);
- $ldap_queries[$query_id]['userscope']: Opseg LDAP pretraživanja korisnika (odabrat će se samo kandidati za korisnike koji odgovaraju kombinaciji userbase+scope);
- $ldap_queries[$query_id]['userfilter']: Filter koji se primjenjuje na zapis svakog kandidata za korisnika (na njegove atribute) radi dodatnog odabira.
Što je s Active Directoryjem?
Active Directory (AD) je Microsoftov registar kojem se može pristupiti upitima putem LDAP protokola.
Njegov se sadržaj stoga može koristiti za LimeSurvey upite tokena, no za to je potrebno znati kako je AD organiziran.
- Korijen LDAP-a (root base) je dc=my_windows_domain_name,dc=dns_suffix2,dc=dns_suffix1
==> Na primjer, ako vaša tvrtka posjeduje DNS domenu 'my-company.com', a vaša Windows domena je 'employees', tada je vaš korijen dc=employees,dc=my-company,dc=com
- Korisnici i grupe korisnika pohranjeni su ispod cn=Users,dc=my_windows_domain_name,dc=dns_suffix2,dc=dns_suffix1 (imajte na umu da to nije ou=users);
- Grupe u Active Directoryju:
- Objekti grupa sadrže DN članova u svojem atributu 'member';
- Članstva u grupama pohranjena su i u atributu memberOf svakog korisničkog unosa. Taj atribut sadrži DN-ove grupa kojima korisnik pripada;
- neke grupe nalaze se u CN=Builtin,dc=my_windows_domain_name,dc=dns_suffix2,dc=dns_suffix1:
- Na primjer: cn=Administrator,CN=Builtin,dc=my_windows_domain_name,dc=dns_suffix2,dc=dns_suffix1;
U nekim slučajevima nije lako izvršiti upit nad Active Directoryjem, pa je ovdje prikazan primjer konfiguracije za dohvaćanje nekih informacija iz Active Directoryja:
//Connection to the active directory Server:
$serverId=0;
$ldap_server[$serverId]['server'] = "10.10.10.10";
$ldap_server[$serverId]['port'] = "389";
$ldap_server[$serverId]['protoversion'] = "ldapv2";
$ldap_server[$serverId]['encrypt'] = "none"; // Most AD LDAP servers will not have encryption set by default
$ldap_server[$serverId]['referrals'] = false;
$ldap_server[$serverId]['binddn'] = "domain\\user";
$ldap_server[$serverId]['bindpw'] = "userpassword";
//$ldap_server[$serverId]['binddn'] = "CN=user,OU=user_group,DC=xxx,DC=yyy"; this one will not work with active directory, that´s why you need to use "domain\\user"
//Here is a sample query for getting all active users of an active directory:
$query_id=0;
$ldap_queries[$query_id]['ldapServerId'] = 0;
$ldap_queries[$query_id]['name'] = 'Staff with an enabled account';
$ldap_queries[$query_id]['userbase'] = 'OU=USER_GROUP,DC=xxx,DC=yyy';
$ldap_queries[$query_id]['userfilter'] = '(&(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))';
//AD has no "account is enabled" attribute, so the filter excludes accounts that have the "disabled" flag (bit 2) set in userAccountControl
$ldap_queries[$query_id]['userscope'] = 'sub';
$ldap_queries[$query_id]['firstname_attr'] = 'givenname';
$ldap_queries[$query_id]['lastname_attr'] = 'sn';
$ldap_queries[$query_id]['email_attr'] = 'mail';
$ldap_queries[$query_id]['token_attr'] = ''; // Leave empty for Auto Token generation by phpsv
$ldap_queries[$query_id]['language'] = '';
$ldap_queries[$query_id]['attr1'] = '';
$ldap_queries[$query_id]['attr2'] = '';
//You can also filter on group membership through the memberOf attribute of the user. Here is a sample query for getting all active users that are member of the group "samplegroup" in active directory:
$query_id++;
$ldap_queries[$query_id]['ldapServerId'] = 0;
$ldap_queries[$query_id]['name'] = 'All members of samplegroup';
$ldap_queries[$query_id]['userbase'] = 'OU=USER_GROUP,DC=xxx,DC=yyy';
$ldap_queries[$query_id]['userfilter'] = '(&(objectClass=user)(memberOf=CN=samplegroup,OU=Group Global,OU=USER_GROUP,DC=xxx,DC=yyy)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))';
$ldap_queries[$query_id]['userscope'] = 'sub';
$ldap_queries[$query_id]['firstname_attr'] = 'givenname';
$ldap_queries[$query_id]['lastname_attr'] = 'sn';
$ldap_queries[$query_id]['email_attr'] = 'mail';
$ldap_queries[$query_id]['token_attr'] = ''; // Leave empty for Auto Token generation by phpsv
$ldap_queries[$query_id]['language'] = '';
$ldap_queries[$query_id]['attr1'] = '';
$ldap_queries[$query_id]['attr2'] = '';
Još jedan primjer korisničkog upita:
$ldap_queries[$query_id]['userfilter'] = '(&(objectCategory=Person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))'; // AD doesn't recognise enabled accounts in the normal way, so instead, we check users are not disabled
- Razmislite o dodavanju (mail=*) u svoje korisničke filtre kako biste preskočili korisnike bez adrese e-pošte.
Primjer upita za grupu:
$ldap_queries[$query_id]['groupfilter'] = '(&(objectClass=group)(cn=Domain Admins))'; // AD doesn't use the standard attribute name for groups, so use this example instead.
Automatsko stvaranje jednog upita po grupi u Active Directoryju
Ako grupe za ispitanike svojeg upitnika držite u jednoj organizacijskoj jedinici (OU), ne morate pisati upit za svaku grupu. Sljedeći kôd ispisuje popis svih grupa u toj OU i stvara jedan upit po grupi. Upit uključuje sve aktivne članove grupe, uključujući članove ugniježđenih grupa.
Dodajte kôd u config/ldap.php nakon definicija poslužitelja i upita, a prije retka //DO NOT CHANGE BELOW HERE. Zatim postavite četiri varijable na vrhu:
- $groupServerId: $serverId poslužitelja koji će se koristiti;
- $groupContainer: DN organizacijske jedinice (OU) koja sadrži grupe. Navode se samo grupe izravno u toj OU, ne i grupe u podjedinicama;
- $groupUserBase: korijenski DN unutar kojeg se traže članovi grupa;
- $groupNameAttr: atribut grupe (malim slovima) koji se koristi kao naziv upita u korisničkom sučelju, na primjer 'info' (polje "Notes" u "Active Directory Users and Computers") ili 'description'. Ako grupa nema vrijednost u tom atributu, koristi se njezin cn.
$groupServerId = 0;
$groupContainer = 'OU=Survey groups,DC=xxx,DC=yyy';
$groupUserBase = 'DC=xxx,DC=yyy';
$groupNameAttr = 'info';
$srv = $ldap_server[$groupServerId];
$ds = ldap_connect(($srv['encrypt'] == 'ldaps' ? 'ldaps://' : 'ldap://') . $srv['server'] . ':' . $srv['port']);
if ($ds) {
ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $srv['protoversion'] == 'ldapv3' ? 3 : 2);
ldap_set_option($ds, LDAP_OPT_REFERRALS, 0);
// Never send the bind password if Start-TLS was requested but failed
$secure = $srv['encrypt'] != 'start-tls' || @ldap_start_tls($ds);
$bound = $secure && (empty($srv['binddn']) ? @ldap_bind($ds) : @ldap_bind($ds, $srv['binddn'], $srv['bindpw']));
$result = $bound ? @ldap_list($ds, $groupContainer, '(objectCategory=group)', array('cn', $groupNameAttr)) : false;
$groups = $result ? ldap_get_entries($ds, $result) : array('count' => 0);
for ($i = 0; $i < $groups['count']; $i++) {
$query_id++;
$ldap_queries[$query_id]['ldapServerId'] = $groupServerId;
$ldap_queries[$query_id]['name'] = isset($groups[$i][$groupNameAttr][0]) ? $groups[$i][$groupNameAttr][0] : $groups[$i]['cn'][0];
$ldap_queries[$query_id]['userbase'] = $groupUserBase;
// Enabled users with an email address that are members of the group, directly or through nested groups
$ldap_queries[$query_id]['userfilter'] = '(&(objectCategory=person)(objectClass=user)(mail=*)'
. '(!(userAccountControl:1.2.840.113556.1.4.803:=2))'
. '(memberOf:1.2.840.113556.1.4.1941:=' . ldap_escape($groups[$i]['dn'], '', LDAP_ESCAPE_FILTER) . '))';
$ldap_queries[$query_id]['userscope'] = 'sub';
$ldap_queries[$query_id]['firstname_attr'] = 'givenname';
$ldap_queries[$query_id]['lastname_attr'] = 'sn';
$ldap_queries[$query_id]['email_attr'] = 'mail';
$ldap_queries[$query_id]['token_attr'] = '';
$ldap_queries[$query_id]['language'] = '';
$ldap_queries[$query_id]['attr1'] = '';
$ldap_queries[$query_id]['attr2'] = '';
}
ldap_unbind($ds);
}
Što treba imati na umu:
- Kôd se povezuje s direktorijem svaki put kada se stranica "Uvezite ispitanike iz LDAP-a" otvori ili pošalje, pa se nove grupe pojavljuju bez promjene konfiguracije. Ako povezivanje ili bind ne uspije, stranica prikazuje samo upite koje ste ručno definirali.
- Pravilo podudaranja 1.2.840.113556.1.4.1941 (LDAP_MATCHING_RULE_IN_CHAIN) razrješava ugniježđene grupe. Postoji samo u Active Directoryju, pa ovaj primjer ne radi s drugim LDAP poslužiteljima. Na njima umjesto toga za svaku grupu koristite kombinirani upit grupe.
- Za popis grupa i u podjedinicama (sub-OU) od $groupContainer zamijenite ldap_list s ldap_search.
- Za popis grupa iz više od jedne OU ponovite kôd s drugim vrijednostima za te četiri varijable.
Više informacija o strukturi LDAP-a u Active Directoryju potražite na Active Directory Architecture i Active Directory Technical Specification.