2 /*******************************************************************************
3 * Copyright (C) 2007 Easter-eggs
4 * http://ldapsaisie.labs.libre-entreprise.org
6 * Author: See AUTHORS file in top-level directory.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 ******************************************************************************/
24 * Gestion des sessions
26 * Cette classe gère les sessions d'utilisateurs.
28 * @author Benjamin Renard <brenard@easter-eggs.com>
32 // La configuration du serveur Ldap utilisé
33 public static $ldapServer = NULL;
35 // L'id du serveur Ldap utilisé
36 private static $ldapServerId = NULL;
39 private static $topDn = NULL;
41 // Le DN de l'utilisateur connecté
42 private static $dn = NULL;
44 // Le RDN de l'utilisateur connecté (son identifiant)
45 private static $rdn = NULL;
47 // Les LSprofiles de l'utilisateur
48 private static $LSprofiles = array();
50 // Les droits d'accès de l'utilisateur
51 private static $LSaccess = array();
53 // Les fichiers temporaires
54 private static $tmp_file = array();
56 // Langue et encodage actuel
57 private static $lang = NULL;
58 private static $encoding = NULL;
61 * Constante de classe non stockée en session
63 // Le template à afficher
64 private static $template = NULL;
66 // Les subDn des serveurs Ldap
67 private static $_subDnLdapServer = array();
70 private static $ajaxDisplay = false;
72 // Les fichiers JS à charger dans la page
73 private static $JSscripts = array();
75 // Les paramètres JS à communiquer dans la page
76 private static $_JSconfigParams = array();
78 // Les fichiers CSS à charger dans la page
79 private static $CssFiles = array();
81 // L'objet de l'utilisateur connecté
82 private static $LSuserObject = NULL;
84 // The LSauht object of the session
85 private static $LSauthObject = false;
88 * Include un fichier PHP
90 * @author Benjamin Renard <brenard@easter-eggs.com>
92 * @retval true si tout c'est bien passé, false sinon
94 public static function includeFile($file) {
95 if (file_exists(LS_LOCAL_DIR.'/'.$file)) {
96 $file=LS_LOCAL_DIR.'/'.$file;
98 elseif (!file_exists($file)) {
101 if (defined('LSdebug') && constant('LSdebug')) {
102 return include_once($file);
105 return @include_once($file);
111 * Lancement de LSconfig
113 * @author Benjamin Renard <brenard@easter-eggs.com>
115 * @retval true si tout c'est bien passé, false sinon
117 private static function startLSconfig() {
118 if (self :: loadLSclass('LSconfig')) {
119 if (LSconfig :: start()) {
123 die("ERROR : Can't load configuration files.");
128 * Lancement et initialisation de Smarty
130 * @author Benjamin Renard <brenard@easter-eggs.com>
132 * @retval true si tout c'est bien passé, false sinon
134 private static function startLStemplate() {
135 if ( self :: loadLSclass('LStemplate') ) {
136 $res = LStemplate :: start(
138 'smarty_path' => LSconfig :: get('Smarty'),
139 'template_dir' => LS_TEMPLATES_DIR,
140 'image_dir' => LS_IMAGES_DIR,
141 'compile_dir' => LS_TMP_DIR,
143 'debug_smarty' => (isset($_REQUEST['LStemplate_debug'])),
146 self :: addJSconfigParam('LS_IMAGES_DIR',LStemplate :: getDefaultImageDirPath());
153 * Retourne le topDn de la session
155 * @author Benjamin Renard <brenard@easter-eggs.com>
157 * @retval string le topDn de la session
159 public static function getTopDn() {
160 if (!is_null(self :: $topDn)) {
161 return self :: $topDn;
164 return self :: getRootDn();
169 * Retourne le rootDn de la session
171 * @author Benjamin Renard <brenard@easter-eggs.com>
173 * @retval string le rootDn de la session
175 public static function getRootDn() {
176 return self :: $ldapServer['ldap_config']['basedn'];
180 * Initialisation de la gestion des erreurs
182 * Création de l'objet LSerror
184 * @author Benjamin Renard <brenard@easter-eggs.com
186 * @retval boolean true si l'initialisation a réussi, false sinon.
188 private static function startLSerror() {
189 if(!self :: loadLSclass('LSerror')) {
192 self :: defineLSerrors();
197 * Chargement d'une classe d'LdapSaisie
199 * @param[in] $class Nom de la classe à charger (Exemple : LSpeople)
200 * @param[in] $type (Optionnel) Type de classe à charger (Exemple : LSobjects)
202 * @author Benjamin Renard <brenard@easter-eggs.com
204 * @retval boolean true si le chargement a réussi, false sinon.
206 public static function loadLSclass($class,$type='') {
207 if (class_exists($class))
211 return self :: includeFile(LS_CLASS_DIR .'class.'.$type.$class.'.php');
215 * Chargement d'un object LdapSaisie
217 * @param[in] $object Nom de l'objet à charger
219 * @retval boolean true si le chargement a réussi, false sinon.
221 public static function loadLSobject($object) {
222 if(class_exists($object)) {
226 self :: loadLSclass('LSldapObject');
227 if (!self :: loadLSclass($object,'LSobjects')) {
230 if (!self :: includeFile( LS_OBJECTS_DIR . 'config.LSobjects.'.$object.'.php' )) {
234 if (!LSconfig :: set("LSobjects.$object",$GLOBALS['LSobjects'][$object])) {
237 else if (isset($GLOBALS['LSobjects'][$object]['LSaddons'])){
238 if (is_array($GLOBALS['LSobjects'][$object]['LSaddons'])) {
239 foreach ($GLOBALS['LSobjects'][$object]['LSaddons'] as $addon) {
240 if (!self :: loadLSaddon($addon)) {
246 if (!self :: loadLSaddon($GLOBALS['LSobjects'][$object]['LSaddons'])) {
253 LSerror :: addErrorCode('LSsession_04',$object);
260 * Chargement d'un addons d'LdapSaisie
262 * @param[in] $addon Nom de l'addon à charger (Exemple : samba)
264 * @author Benjamin Renard <brenard@easter-eggs.com
266 * @retval boolean true si le chargement a réussi, false sinon.
268 public static function loadLSaddon($addon) {
269 if(self :: includeFile(LS_ADDONS_DIR .'LSaddons.'.$addon.'.php')) {
270 self :: includeFile(LS_CONF_DIR."LSaddons/config.LSaddons.".$addon.".php");
271 if (!call_user_func('LSaddon_'. $addon .'_support')) {
272 LSerror :: addErrorCode('LSsession_02',$addon);
281 * Chargement d'une classe d'authentification d'LdapSaisie
283 * @author Benjamin Renard <brenard@easter-eggs.com
285 * @retval boolean true si le chargement a reussi, false sinon.
287 public static function loadLSauth() {
288 if (self :: loadLSclass('LSauth')) {
292 LSerror :: addErrorCode('LSsession_05','LSauth');
298 * Chargement des addons LdapSaisie
300 * Chargement des LSaddons contenue dans la variable
301 * $GLOBALS['LSaddons']['loads']
303 * @retval boolean true si le chargement a réussi, false sinon.
305 public static function loadLSaddons() {
306 $conf=LSconfig :: get('LSaddons.loads');
307 if(!is_array($conf)) {
308 LSerror :: addErrorCode('LSsession_01',"LSaddons['loads']");
312 foreach ($conf as $addon) {
313 self :: loadLSaddon($addon);
323 public static function setLocale() {
324 if (isset($_REQUEST['lang'])) {
325 $lang = $_REQUEST['lang'];
327 elseif (isset($_SESSION['LSlang'])) {
328 $lang = $_SESSION['LSlang'];
330 elseif (isset(self :: $ldapServer['lang'])) {
331 $lang = self :: $ldapServer['lang'];
334 $lang = LSconfig :: get('lang');
337 if (isset($_REQUEST['encoding'])) {
338 $encoding = $_REQUEST['encoding'];
340 elseif (isset($_SESSION['LSencoding'])) {
341 $encoding = $_SESSION['LSencoding'];
343 elseif (isset(self :: $ldapServer['encoding'])) {
344 $encoding = self :: $ldapServer['encoding'];
347 $encoding = LSconfig :: get('encoding');
350 $_SESSION['LSlang']=$lang;
352 $_SESSION['LSencoding']=$encoding;
353 self :: $encoding=$encoding;
356 if (self :: localeExist($lang,$encoding)) {
358 $lang.='.'.$encoding;
360 setlocale(LC_ALL, $lang);
361 bindtextdomain(LS_TEXT_DOMAIN, LS_I18N_DIR);
362 textdomain(LS_TEXT_DOMAIN);
364 self :: includeFile(LS_I18N_DIR.'/'.$lang.'/lang.php');
366 foreach (listFiles(LS_LOCAL_DIR.'/'.LS_I18N_DIR.'/'.$lang,'/^lang.+\.php$/') as $file) {
367 include(LS_LOCAL_DIR.'/'.LS_I18N_DIR."/$lang/$file");
371 if ($encoding && $lang) {
372 $lang.='.'.$encoding;
374 LSdebug('La locale "'.$lang.'" n\'existe pas, utilisation de la locale par défaut.');
379 * Retourne la liste des langues disponibles
381 * @retval array Tableau/Liste des langues disponibles
383 public static function getLangList() {
384 $list=array('en_US');
385 if (self :: $encoding) {
386 $regex = '^([a-zA-Z_]*)\.'.self :: $encoding.'$';
389 $regex = '^([a-zA-Z_]*)$';
391 if ($handle = opendir(LS_I18N_DIR)) {
392 while (false !== ($file = readdir($handle))) {
393 if(is_dir(LS_I18N_DIR.'/'.$file)) {
394 if (ereg($regex,$file,$regs)) {
395 if (!in_array($regs[1],$list)) {
406 * Retourne la langue courante de la session
408 * @param[in] boolean Si true, le code langue retourné sera court
410 * @retval string La langue de la session
412 public static function getLang($short=false) {
414 return strtolower(self :: $lang[0].self :: $lang[1]);
416 return self :: $lang;
420 * Vérifie si une locale est disponible
422 * @param[in] $lang string La langue (Ex : fr_FR)
423 * @param[in] $encoding string L'encodage de caractère (Ex : UTF8)
425 * @retval boolean True si la locale est disponible, False sinon
427 public static function localeExist($lang,$encoding) {
428 if ( !$lang && !$encoding ) {
431 $locale=$lang.(($encoding)?'.'.$encoding:'');
432 if ($locale=='en_US.UTF8') {
435 return (is_dir(LS_I18N_DIR.'/'.$locale));
439 * Initialisation LdapSaisie
441 * @retval boolean True si l'initialisation à réussi, false sinon.
443 public static function initialize() {
444 if (!self :: startLSconfig()) {
448 self :: startLSerror();
449 self :: startLStemplate();
455 self :: loadLSaddons();
456 self :: loadLSauth();
461 * Initialisation de la session LdapSaisie
463 * Initialisation d'une LSsession :
464 * - Authentification et activation du mécanisme de session de LdapSaisie
465 * - ou Chargement des paramètres de la session à partir de la variable
466 * $_SESSION['LSsession'].
467 * - ou Destruction de la session en cas de $_GET['LSsession_logout'].
469 * @retval boolean True si l'initialisation à réussi (utilisateur authentifié), false sinon.
471 public static function startLSsession() {
472 if (!self :: initialize()) {
476 if(isset($_SESSION['LSsession']['dn']) && !isset($_GET['LSsession_recoverPassword'])) {
477 LSdebug('LSsession : Session existente');
478 // --------------------- Session existante --------------------- //
479 self :: $topDn = $_SESSION['LSsession']['topDn'];
480 self :: $dn = $_SESSION['LSsession']['dn'];
481 self :: $rdn = $_SESSION['LSsession']['rdn'];
482 self :: $ldapServerId = $_SESSION['LSsession']['ldapServerId'];
483 self :: $tmp_file = $_SESSION['LSsession']['tmp_file'];
485 if ( self :: cacheLSprofiles() && !isset($_REQUEST['LSsession_refresh']) ) {
486 self :: setLdapServer(self :: $ldapServerId);
487 if (!LSauth :: start()) {
488 LSdebug("LSsession : can't start LSauth -> stop");
491 self :: $LSprofiles = $_SESSION['LSsession']['LSprofiles'];
492 self :: $LSaccess = $_SESSION['LSsession']['LSaccess'];
493 if (!self :: LSldapConnect())
497 self :: setLdapServer(self :: $ldapServerId);
498 if (!LSauth :: start()) {
499 LSdebug("LSsession : can't start LSauth -> stop");
502 if (!self :: LSldapConnect())
504 self :: loadLSprofiles();
507 if ( self :: cacheSudDn() && (!isset($_REQUEST['LSsession_refresh'])) ) {
508 self :: $_subDnLdapServer = ((isset($_SESSION['LSsession_subDnLdapServer']))?$_SESSION['LSsession_subDnLdapServer']:NULL);
511 if (!self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
515 if (isset($_GET['LSsession_logout'])) {
519 if (is_array($_SESSION['LSsession']['tmp_file'])) {
520 self :: $tmp_file = $_SESSION['LSsession']['tmp_file'];
522 self :: deleteTmpFile();
523 unset($_SESSION['LSsession']);
525 self :: redirect('index.php');
529 if ( !self :: cacheLSprofiles() || isset($_REQUEST['LSsession_refresh']) ) {
530 self :: loadLSaccess();
533 LStemplate :: assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
535 if (isset ($_POST['LSsession_topDn']) && $_POST['LSsession_topDn']) {
536 if (self :: validSubDnLdapServer($_POST['LSsession_topDn'])) {
537 self :: $topDn = $_POST['LSsession_topDn'];
538 $_SESSION['LSsession']['topDn'] = $_POST['LSsession_topDn'];
546 // --------------------- Session inexistante --------------------- //
547 if (isset($_GET['LSsession_recoverPassword'])) {
550 // Session inexistante
551 if (isset($_POST['LSsession_ldapserver'])) {
552 self :: setLdapServer($_POST['LSsession_ldapserver']);
555 self :: setLdapServer(0);
558 // Connexion au serveur LDAP
559 if (self :: LSldapConnect()) {
562 if (isset($_POST['LSsession_topDn']) && $_POST['LSsession_topDn'] != '' ){
563 self :: $topDn = $_POST['LSsession_topDn'];
566 self :: $topDn = self :: $ldapServer['ldap_config']['basedn'];
568 $_SESSION['LSsession_topDn']=self :: $topDn;
570 if (!LSauth :: start()) {
571 LSdebug("LSsession : can't start LSauth -> stop");
575 if (isset($_GET['LSsession_recoverPassword'])) {
576 $recoveryPasswordInfos = self :: recoverPasswd(
577 $_REQUEST['LSsession_user'],
578 $_GET['recoveryHash']
582 $LSuserObject = LSauth :: forceAuthentication();
584 // Authentication successful
585 self :: $LSuserObject = $LSuserObject;
586 self :: $dn = $LSuserObject->getValue('dn');
587 self :: $rdn = $LSuserObject->getValue('rdn');
588 self :: loadLSprofiles();
589 self :: loadLSaccess();
590 LStemplate :: assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
591 $_SESSION['LSsession']=self :: getContextInfos();
597 LSerror :: addErrorCode('LSsession_09');
600 if (self :: $ldapServerId) {
601 LStemplate :: assign('ldapServerId',self :: $ldapServerId);
603 LStemplate :: assign('topDn',self :: $topDn);
604 if (isset($_GET['LSsession_recoverPassword'])) {
605 self :: displayRecoverPasswordForm($recoveryPasswordInfos);
607 elseif(LSauth :: displayLoginForm()) {
608 self :: displayLoginForm();
611 self :: setTemplate('blank.tpl');
612 LSerror :: addErrorCode('LSsession_10');
619 * Do recover password
621 * @param[in] $username string The submited username
622 * @param[in] $recoveryHash string The submited recoveryHash
624 * @retval array The recoveryPassword infos for template
626 private static function recoverPasswd($username,$recoveryHash) {
627 $recoveryPasswordInfos=array();
628 if ( self :: loadLSobject(self :: $ldapServer['authObjectType']) ) {
629 $authobject = new self :: $ldapServer['authObjectType']();
630 if (!empty($recoveryHash)) {
631 $filter=Net_LDAP2_Filter::create(
632 self :: $ldapServer['recoverPassword']['recoveryHashAttr'],
636 $result = $authobject -> listObjects($filter,self :: $topDn);
638 elseif (!empty($username)) {
639 $result = $authobject -> searchObject(
642 self :: $ldapServer['authObjectFilter']
646 return $recoveryPasswordInfos;
649 $nbresult=count($result);
652 LSdebug('hash/username incorrect');
653 LSerror :: addErrorCode('LSsession_06');
655 elseif ($nbresult>1) {
656 LSerror :: addErrorCode('LSsession_07');
659 $rdn = $result[0] -> getValue('rdn');
661 LSdebug('Recover : Id trouvé : '.$username);
662 if (self :: $ldapServer['recoverPassword']) {
663 if (self :: loadLSaddon('mail')) {
664 LSdebug('Récupération active');
666 $emailAddress = $user -> getValue(self :: $ldapServer['recoverPassword']['mailAttr']);
667 $emailAddress = $emailAddress[0];
669 if (checkEmail($emailAddress)) {
670 LSdebug('Email : '.$emailAddress);
671 self :: $dn = $user -> getDn();
673 // 1ère étape : envoie du recoveryHash
674 if (empty($recoveryHash)) {
675 $hash=self :: recoverPasswdFirstStep($user);
677 if (self :: recoverPasswdSendMail($emailAddress,1,$hash)) {
678 // Mail a bien été envoyé
679 $recoveryPasswordInfos['recoveryHashMail']=$emailAddress;
683 // 2nd étape : génération du mot de passe + envoie par mail
685 $pwd=self :: recoverPasswdSecondStep($user);
687 if (self :: recoverPasswdSendMail($emailAddress,2,$pwd)){
688 // Mail a bien été envoyé
689 $recoveryPasswordInfos['newPasswordMail']=$emailAddress;
695 LSerror :: addErrorCode('LSsession_19');
700 LSerror :: addErrorCode('LSsession_18');
704 return $recoveryPasswordInfos;
708 * Send recover password mail
710 * @param[in] $mail string The user's mail
711 * @param[in] $step integer The step
712 * @param[in] $info string The info for formatted message
714 * @retval boolean True on success or False
716 private static function recoverPasswdSendMail($mail,$step,$info) {
719 if (self :: $ldapServer['recoverPassword']['recoveryEmailSender']) {
720 $sendParams['From']=self :: $ldapServer['recoverPassword']['recoveryEmailSender'];
724 if ($_SERVER['HTTPS']=='on') {
725 $recovery_url='https://';
728 $recovery_url='http://';
730 $recovery_url .= $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'&recoveryHash='.$info;
732 $subject = self :: $ldapServer['recoverPassword']['recoveryHashMail']['subject'];
734 self :: $ldapServer['recoverPassword']['recoveryHashMail']['msg'],
739 $subject = self :: $ldapServer['recoverPassword']['newPasswordMail']['subject'];
741 self :: $ldapServer['recoverPassword']['newPasswordMail']['msg'],
746 if (!sendMail($mail,$subject,$msg,$sendParams)) {
747 LSdebug("Problème durant l'envoie du mail");
748 LSerror :: addErrorCode('LSsession_20',4);
756 * Do first step of recovering password
758 * @param[in] $user LSldapObject The LSldapObject of the user
760 * @retval string|False The recory hash on success or False
762 private static function recoverPasswdFirstStep($user) {
764 $rdn=$user -> getValue('rdn');
766 $recovery_hash = md5($rdn . strval(time()) . strval(rand()));
768 $lostPasswdForm = $user -> getForm('lostPassword');
769 $lostPasswdForm -> setPostData(
771 self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => $recovery_hash
776 if($lostPasswdForm -> validate()) {
777 if ($user -> updateData('lostPassword')) {
778 // recoveryHash de l'utilisateur mis à jour
779 return $recovery_hash;
782 // Erreur durant la mise à jour de l'objet
783 LSdebug("Erreur durant la mise à jour de l'objet");
784 LSerror :: addErrorCode('LSsession_20',6);
788 // Erreur durant la validation du formulaire de modification de perte de password
789 LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
790 LSerror :: addErrorCode('LSsession_20',5);
796 * Do second step of recovering password
798 * @param[in] $user LSldapObject The LSldapObject of the user
800 * @retval string|False The new password on success or False
802 private static function recoverPasswdSecondStep($user) {
803 $attr=$user -> attrs[self :: $ldapServer['authObjectTypeAttrPwd']];
804 if ($attr instanceof LSattribute) {
805 $mdp = generatePassword(
806 $attr -> config['html_options']['chars'],
807 $attr -> config['html_options']['lenght']
809 LSdebug('Nvx mpd : '.$mdp);
810 $lostPasswdForm = $user -> getForm('lostPassword');
811 $lostPasswdForm -> setPostData(
813 self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => array(''),
814 self :: $ldapServer['authObjectTypeAttrPwd'] => array($mdp)
818 if($lostPasswdForm -> validate()) {
819 if ($user -> updateData('lostPassword')) {
823 // Erreur durant la mise à jour de l'objet
824 LSdebug("Erreur durant la mise à jour de l'objet");
825 LSerror :: addErrorCode('LSsession_20',3);
829 // Erreur durant la validation du formulaire de modification de perte de password
830 LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
831 LSerror :: addErrorCode('LSsession_20',2);
835 // l'attribut password n'existe pas
836 LSdebug("L'attribut password n'existe pas");
837 LSerror :: addErrorCode('LSsession_20',1);
843 * Retourne les informations du contexte
845 * @author Benjamin Renard <brenard@easter-eggs.com
847 * @retval array Tableau associatif des informations du contexte
849 private static function getContextInfos() {
851 'tmp_file' => self :: $tmp_file,
852 'topDn' => self :: $topDn,
854 'rdn' => self :: $rdn,
855 'ldapServerId' => self :: $ldapServerId,
856 'ldapServer' => self :: $ldapServer,
857 'LSprofiles' => self :: $LSprofiles,
858 'LSaccess' => self :: $LSaccess
863 * Retourne l'objet de l'utilisateur connecté
865 * @author Benjamin Renard <brenard@easter-eggs.com
867 * @retval mixed L'objet de l'utilisateur connecté ou false si il n'a pas put
870 public static function getLSuserObject($dn=null) {
874 if (!self :: $LSuserObject) {
875 if (self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
876 self :: $LSuserObject = new self :: $ldapServer['authObjectType']();
877 self :: $LSuserObject -> loadData(self :: $dn);
883 return self :: $LSuserObject;
887 * Retourne le DN de l'utilisateur connecté
889 * @author Benjamin Renard <brenard@easter-eggs.com
891 * @retval string Le DN de l'utilisateur connecté
893 public static function getLSuserObjectDn() {
898 * Modifie l'utilisateur connecté à la volé
900 * @param[in] $object Mixed L'objet Ldap du nouvel utilisateur
901 * le type doit correspondre à
902 * self :: $ldapServer['authObjectType']
904 * @retval boolean True en cas de succès, false sinon
906 public static function changeAuthUser($object) {
907 if ($object instanceof self :: $ldapServer['authObjectType']) {
908 self :: $dn = $object -> getDn();
909 $rdn = $object -> getValue('rdn');
914 self :: $LSuserObject = $object;
916 if(self :: loadLSprofiles()) {
917 self :: loadLSaccess();
918 $_SESSION['LSsession']=self :: getContextInfos();
926 * Définition du serveur Ldap de la session
928 * Définition du serveur Ldap de la session à partir de son ID dans
929 * le tableau LSconfig :: get('ldap_servers').
931 * @param[in] integer Index du serveur Ldap
933 * @retval boolean True sinon false.
935 public static function setLdapServer($id) {
936 $conf = LSconfig :: get("ldap_servers.$id");
937 if ( is_array($conf) ) {
938 self :: $ldapServerId = $id;
939 self :: $ldapServer = $conf;
949 * Connexion au serveur Ldap
951 * @retval boolean True sinon false.
953 public static function LSldapConnect() {
954 if (self :: $ldapServer) {
955 self :: includeFile(LSconfig :: get('NetLDAP2'));
956 if (!self :: loadLSclass('LSldap')) {
959 LSldap :: connect(self :: $ldapServer['ldap_config']);
960 if (LSldap :: isConnected()) {
968 LSerror :: addErrorCode('LSsession_03');
974 * Use this function to know if subDn is enabled for the curent LdapServer
978 public static function subDnIsEnabled() {
979 if (!isset(self :: $ldapServer['subDn'])) {
982 if ( !is_array(self :: $ldapServer['subDn']) ) {
989 * Retourne les sous-dns du serveur Ldap courant
991 * @retval mixed Tableau des subDn, false si une erreur est survenue.
993 public static function getSubDnLdapServer($login=false) {
995 if (self :: cacheSudDn() && isset(self :: $_subDnLdapServer[self :: $ldapServerId][$login])) {
996 return self :: $_subDnLdapServer[self :: $ldapServerId][$login];
998 if (!self::subDnIsEnabled()) {
1002 foreach(self :: $ldapServer['subDn'] as $subDn_name => $subDn_config) {
1003 if ($login && isset($subDn_config['nologin']) && $subDn_config['nologin']) continue;
1004 if ($subDn_name == 'LSobject') {
1005 if (is_array($subDn_config)) {
1006 foreach($subDn_config as $LSobject_name => $LSoject_config) {
1007 if (isset($LSoject_config['basedn']) && !empty($LSoject_config['basedn'])) {
1008 $basedn = $LSoject_config['basedn'];
1011 $basedn = self::getRootDn();
1013 if (isset($LSoject_config['displayName']) && !empty($LSoject_config['displayName'])) {
1014 $displayName = $LSoject_config['displayName'];
1017 $displayName = NULL;
1019 if( self :: loadLSobject($LSobject_name) ) {
1020 if ($subdnobject = new $LSobject_name()) {
1021 $tbl_return = $subdnobject -> getSelectArray(NULL,$basedn,$displayName);
1022 if (is_array($tbl_return)) {
1023 $return=array_merge($return,$tbl_return);
1026 LSerror :: addErrorCode('LSsession_17',3);
1030 LSerror :: addErrorCode('LSsession_17',2);
1036 LSerror :: addErrorCode('LSsession_17',1);
1040 if ((isCompatibleDNs($subDn_config['dn'],self :: $ldapServer['ldap_config']['basedn']))&&($subDn_config['dn']!="")) {
1041 $return[$subDn_config['dn']] = __($subDn_name);
1045 if (self :: cacheSudDn()) {
1046 self :: $_subDnLdapServer[self :: $ldapServerId][$login]=$return;
1047 $_SESSION['LSsession_subDnLdapServer'] = self :: $_subDnLdapServer;
1053 * Retourne la liste de subDn du serveur Ldap utilise
1054 * trié par la profondeur dans l'arboressence (ordre décroissant)
1056 * @return array() Tableau des subDn trié
1058 public static function getSortSubDnLdapServer($login=false) {
1059 $subDnLdapServer = self :: getSubDnLdapServer($login);
1060 if (!$subDnLdapServer) {
1063 uksort($subDnLdapServer,"compareDn");
1064 return $subDnLdapServer;
1068 * Retourne les options d'une liste déroulante pour le choix du topDn
1069 * de connexion au serveur Ldap
1071 * Liste les subdn (self :: $ldapServer['subDn'])
1073 * @retval string Les options (<option>) pour la sélection du topDn.
1075 public static function getSubDnLdapServerOptions($selected=NULL,$login=false) {
1076 $list = self :: getSubDnLdapServer($login);
1080 foreach($list as $dn => $txt) {
1081 if ($selected && ($selected==$dn)) {
1082 $selected_txt = ' selected';
1087 $display.="<option value=\"".$dn."\"$selected_txt>".$txt."</option>\n";
1095 * Vérifie qu'un subDn est déclaré
1097 * @param[in] string Un subDn
1099 * @retval boolean True si le subDn existe, False sinon
1101 public static function validSubDnLdapServer($subDn) {
1102 $listTopDn = self :: getSubDnLdapServer();
1103 if(is_array($listTopDn)) {
1104 foreach($listTopDn as $dn => $txt) {
1114 * Test un couple LSobject/pwd
1116 * Test un bind sur le serveur avec le dn de l'objet et le mot de passe fourni.
1118 * @param[in] LSobject L'object "user" pour l'authentification
1119 * @param[in] string Le mot de passe à tester
1121 * @retval boolean True si l'authentification à réussi, false sinon.
1123 public static function checkUserPwd($object,$pwd) {
1124 return LSldap :: checkBind($object -> getValue('dn'),$pwd);
1128 * Affiche le formulaire de login
1130 * Défini les informations pour le template Smarty du formulaire de login.
1134 public static function displayLoginForm() {
1135 LStemplate :: assign('pagetitle',_('Connection'));
1136 if (isset($_GET['LSsession_logout'])) {
1137 LStemplate :: assign('loginform_action','index.php');
1140 LStemplate :: assign('loginform_action',$_SERVER['REQUEST_URI']);
1142 if (count(LSconfig :: get('ldap_servers'))==1) {
1143 LStemplate :: assign('loginform_ldapserver_style','style="display: none"');
1145 LStemplate :: assign('loginform_label_ldapserver',_('LDAP server'));
1146 $ldapservers_name=array();
1147 $ldapservers_index=array();
1148 foreach(LSconfig :: get('ldap_servers') as $id => $infos) {
1149 $ldapservers_index[]=$id;
1150 $ldapservers_name[]=__($infos['name']);
1152 LStemplate :: assign('loginform_ldapservers_name',$ldapservers_name);
1153 LStemplate :: assign('loginform_ldapservers_index',$ldapservers_index);
1155 LStemplate :: assign('loginform_label_level',_('Level'));
1156 LStemplate :: assign('loginform_label_user',_('Identifier'));
1157 LStemplate :: assign('loginform_label_pwd',_('Password'));
1158 LStemplate :: assign('loginform_label_submit',_('Connect'));
1159 LStemplate :: assign('loginform_label_recoverPassword',_('Forgot your password ?'));
1161 self :: setTemplate('login.tpl');
1162 self :: addJSscript('LSsession_login.js');
1166 * Affiche le formulaire de récupération de mot de passe
1168 * Défini les informations pour le template Smarty du formulaire de
1169 * récupération de mot de passe
1171 * @param[in] $infos array() Information sur le status du processus de
1172 * recouvrement de mot de passe
1176 public static function displayRecoverPasswordForm($recoveryPasswordInfos) {
1177 LStemplate :: assign('pagetitle',_('Recovery of your credentials'));
1178 LStemplate :: assign('recoverpasswordform_action','index.php?LSsession_recoverPassword');
1180 if (count(LSconfig :: get('ldap_servers'))==1) {
1181 LStemplate :: assign('recoverpasswordform_ldapserver_style','style="display: none"');
1184 LStemplate :: assign('recoverpasswordform_label_ldapserver',_('LDAP server'));
1185 $ldapservers_name=array();
1186 $ldapservers_index=array();
1187 foreach(LSconfig :: get('ldap_servers') as $id => $infos) {
1188 $ldapservers_index[]=$id;
1189 $ldapservers_name[]=$infos['name'];
1191 LStemplate :: assign('recoverpasswordform_ldapservers_name',$ldapservers_name);
1192 LStemplate :: assign('recoverpasswordform_ldapservers_index',$ldapservers_index);
1194 LStemplate :: assign('recoverpasswordform_label_user',_('Identifier'));
1195 LStemplate :: assign('recoverpasswordform_label_submit',_('Validate'));
1196 LStemplate :: assign('recoverpasswordform_label_back',_('Back'));
1198 $recoverpassword_msg = _('Please fill the identifier field to proceed recovery procedure');
1200 if (isset($recoveryPasswordInfos['recoveryHashMail'])) {
1201 $recoverpassword_msg = getFData(
1202 _("An email has been sent to %{mail}. " .
1203 "Please follow the instructions on it."),
1204 $recoveryPasswordInfos['recoveryHashMail']
1208 if (isset($recoveryPasswordInfos['newPasswordMail'])) {
1209 $recoverpassword_msg = getFData(
1210 _("Your new password has been sent to %{mail}. "),
1211 $recoveryPasswordInfos['newPasswordMail']
1215 LStemplate :: assign('recoverpassword_msg',$recoverpassword_msg);
1217 self :: setTemplate('recoverpassword.tpl');
1218 self :: addJSscript('LSsession_recoverPassword.js');
1222 * Défini le template Smarty à utiliser
1224 * Remarque : les fichiers de templates doivent se trouver dans le dossier
1227 * @param[in] string Le nom du fichier de template
1231 public static function setTemplate($template) {
1232 self :: $template = $template;
1236 * Ajoute un script JS au chargement de la page
1238 * Remarque : les scripts doivents être dans le dossier LS_JS_DIR.
1240 * @param[in] $script Le nom du fichier de script à charger.
1244 public static function addJSscript($file,$path=NULL) {
1249 self :: $JSscripts[$path.$file]=$script;
1253 * Ajouter un paramètre de configuration Javascript
1255 * @param[in] $name string Nom de la variable de configuration
1256 * @param[in] $val mixed Valeur de la variable de configuration
1260 public static function addJSconfigParam($name,$val) {
1261 self :: $_JSconfigParams[$name]=$val;
1265 * Ajoute une feuille de style au chargement de la page
1267 * Remarque : les scripts doivents être dans le dossier LS_CSS_DIR.
1269 * @param[in] $script Le nom du fichier css à charger.
1273 public static function addCssFile($file,$path=NULL) {
1278 self :: $CssFiles[$path.$file]=$cssFile;
1282 * Affiche le template Smarty
1284 * Charge les dépendances et affiche le template Smarty
1288 public static function displayTemplate() {
1291 foreach ($GLOBALS['defaultJSscipts'] as $script) {
1292 $JSscript_txt.="<script src='".LS_JS_DIR.$script."' type='text/javascript'></script>\n";
1295 foreach (self :: $JSscripts as $script) {
1296 if (!$script['path']) {
1297 $script['path']=LS_JS_DIR;
1300 $script['path'].='/';
1302 $JSscript_txt.="<script src='".$script['path'].$script['file']."' type='text/javascript'></script>\n";
1305 $KAconf = LSconfig :: get('keepLSsessionActive');
1308 (!isset(self :: $ldapServer['keepLSsessionActive']))
1310 (!($KAconf === false))
1313 (self :: $ldapServer['keepLSsessionActive'])
1315 self :: addJSconfigParam('keepLSsessionActive',ini_get('session.gc_maxlifetime'));
1318 LStemplate :: assign('LSjsConfig',json_encode(self :: $_JSconfigParams));
1321 $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 1;</script>\n";
1324 $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 0;</script>\n";
1327 LStemplate :: assign('LSsession_js',$JSscript_txt);
1330 self :: addCssFile("LSdefault.css");
1332 foreach (self :: $CssFiles as $file) {
1333 if (!$file['path']) {
1334 $file['path']=LS_CSS_DIR.'/';
1336 $Css_txt.="<link rel='stylesheet' type='text/css' href='".$file['path'].$file['file']."' />\n";
1338 LStemplate :: assign('LSsession_css',$Css_txt);
1340 if (isset(self :: $LSaccess[self :: $topDn])) {
1341 LStemplate :: assign('LSaccess',self :: $LSaccess[self :: $topDn]);
1345 $listTopDn = self :: getSubDnLdapServer();
1346 if (is_array($listTopDn)) {
1348 LStemplate :: assign('label_level',self :: getSubDnLabel());
1349 LStemplate :: assign('_refresh',_('Refresh'));
1350 $LSsession_topDn_index = array();
1351 $LSsession_topDn_name = array();
1352 foreach($listTopDn as $index => $name) {
1353 $LSsession_topDn_index[] = $index;
1354 $LSsession_topDn_name[] = $name;
1356 LStemplate :: assign('LSsession_subDn_indexes',$LSsession_topDn_index);
1357 LStemplate :: assign('LSsession_subDn_names',$LSsession_topDn_name);
1358 LStemplate :: assign('LSsession_subDn',self :: $topDn);
1359 LStemplate :: assign('LSsession_subDnName',self :: getSubDnName());
1362 LStemplate :: assign('LSlanguages',self :: getLangList());
1363 LStemplate :: assign('LSlang',self :: $lang);
1364 LStemplate :: assign('LSencoding',self :: $encoding);
1365 LStemplate :: assign('lang_label',_('Language'));
1367 LStemplate :: assign('displayLogoutBtn',LSauth :: displayLogoutBtn());
1368 LStemplate :: assign('displaySelfAccess',LSauth :: displaySelfAccess());
1371 if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
1372 $txt_infos="<ul>\n";
1373 foreach($_SESSION['LSsession_infos'] as $info) {
1374 $txt_infos.="<li>$info</li>\n";
1376 $txt_infos.="</ul>\n";
1377 LStemplate :: assign('LSinfos',$txt_infos);
1378 $_SESSION['LSsession_infos']=array();
1381 if (self :: $ajaxDisplay) {
1382 LStemplate :: assign('LSerror_txt',LSerror :: getErrors());
1383 LStemplate :: assign('LSdebug_txt',LSdebug_print(true));
1386 LSerror :: display();
1389 if (!self :: $template)
1390 self :: setTemplate('empty.tpl');
1392 LStemplate :: assign('connected_as',_("Connected as"));
1394 LStemplate :: display(self :: $template);
1398 * Défini que l'affichage se fera ou non via un retour Ajax
1400 * @param[in] $val boolean True pour que l'affichage se fasse par un retour
1404 public static function setAjaxDisplay($val=true) {
1405 self :: $ajaxDisplay = (boolean)$val;
1409 * Affiche un retour Ajax
1413 public static function displayAjaxReturn($data=array()) {
1414 if (isset($data['LSredirect']) && (!LSdebugDefined()) ) {
1415 echo json_encode($data);
1419 $data['LSjsConfig'] = self :: $_JSconfigParams;
1422 if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
1423 $txt_infos="<ul>\n";
1424 foreach($_SESSION['LSsession_infos'] as $info) {
1425 $txt_infos.="<li>$info</li>\n";
1427 $txt_infos.="</ul>\n";
1428 $data['LSinfos'] = $txt_infos;
1429 $_SESSION['LSsession_infos']=array();
1432 if (LSerror :: errorsDefined()) {
1433 $data['LSerror'] = LSerror :: getErrors();
1436 if (isset($_REQUEST['imgload'])) {
1437 $data['imgload'] = $_REQUEST['imgload'];
1440 if (LSdebugDefined()) {
1441 $data['LSdebug'] = LSdebug_print(true,false);
1444 echo json_encode($data);
1448 * Retournne un template Smarty compilé
1450 * @param[in] string $template Le template à retourner
1451 * @param[in] array $variables Variables Smarty à assigner avant l'affichage
1453 * @retval string Le HTML compilé du template
1455 public static function fetchTemplate($template,$variables=array()) {
1456 foreach($variables as $name => $val) {
1457 LStemplate :: assign($name,$val);
1459 return LStemplate :: fetch($template);
1463 * Charge les droits LS de l'utilisateur
1465 * @retval boolean True si le chargement à réussi, false sinon.
1467 private static function loadLSprofiles() {
1468 if (is_array(self :: $ldapServer['LSprofiles'])) {
1469 foreach (self :: $ldapServer['LSprofiles'] as $profile => $profileInfos) {
1470 if (is_array($profileInfos)) {
1471 foreach ($profileInfos as $topDn => $rightsInfos) {
1473 * If $topDn == 'LSobject', we search for each LSobject type to find
1474 * all items on witch the user will have powers.
1476 if ($topDn == 'LSobjects') {
1477 if (is_array($rightsInfos)) {
1478 foreach ($rightsInfos as $LSobject => $listInfos) {
1479 if (self :: loadLSclass('LSsearch')) {
1480 if (isset($listInfos['filter'])) {
1481 $filter = self :: getLSuserObject() -> getFData($listInfos['filter']);
1484 $filter = '('.$listInfos['attr'].'='.self :: getLSuserObject() -> getFData($listInfos['attr_value']).')';
1488 'basedn' => (isset($listInfos['basedn'])?$listInfos['basedn']:null),
1492 if (isset($listInfos['params']) && is_array($listInfos['params'])) {
1493 $params = array_merge($listInfos['params'],$params);
1496 $LSsearch = new LSsearch($LSobject,'LSsession :: loadLSprofiles',$params,true);
1497 $LSsearch -> run(false);
1499 self :: $LSprofiles[$profile] = $LSsearch -> listObjectsDn();
1504 LSdebug('LSobjects => [] doit etre un tableau');
1508 if (is_array($rightsInfos)) {
1509 foreach($rightsInfos as $dn => $conf) {
1510 if ((isset($conf['attr'])) && (isset($conf['LSobject']))) {
1511 if( self :: loadLSobject($conf['LSobject']) ) {
1512 if ($object = new $conf['LSobject']()) {
1513 if ($object -> loadData($dn)) {
1514 $listDns=$object -> getValue($conf['attr']);
1515 $valKey = (isset($conf['attr_value']))?$conf['attr_value']:'%{dn}';
1516 $val = self :: getLSuserObject() -> getFData($valKey);
1517 if (is_array($listDns)) {
1518 if (in_array($val,$listDns)) {
1519 self :: $LSprofiles[$profile][] = $topDn;
1524 LSdebug('Impossible de chargé le dn : '.$dn);
1528 LSdebug('Impossible de créer l\'objet de type : '.$conf['LSobject']);
1533 if (self :: $dn == $dn) {
1534 self :: $LSprofiles[$profile][] = $topDn;
1540 if ( self :: $dn == $rightsInfos ) {
1541 self :: $LSprofiles[$profile][] = $topDn;
1544 } // fin else ($topDn == 'LSobjects')
1545 } // fin foreach($profileInfos)
1546 } // fin is_array($profileInfos)
1547 } // fin foreach LSprofiles
1548 LSdebug(self :: $LSprofiles);
1557 * Charge les droits d'accès de l'utilisateur pour construire le menu de l'interface
1561 private static function loadLSaccess() {
1563 if (isset(self :: $ldapServer['subDn']) && is_array(self :: $ldapServer['subDn'])) {
1564 foreach(self :: $ldapServer['subDn'] as $name => $config) {
1565 if ($name=='LSobject') {
1566 if (is_array($config)) {
1568 // Définition des subDns
1569 foreach($config as $objectType => $objectConf) {
1570 if (self :: loadLSobject($objectType)) {
1571 if ($subdnobject = new $objectType()) {
1572 $tbl = $subdnobject -> getSelectArray(NULL,self::getRootDn(),NULL,NULL,false);
1573 if (is_array($tbl)) {
1574 // Définition des accès
1576 if (is_array($objectConf['LSobjects'])) {
1577 foreach($objectConf['LSobjects'] as $type) {
1578 if (self :: loadLSobject($type)) {
1579 if (self :: canAccess($type)) {
1580 $access[$type] = LSconfig :: get('LSobjects.'.$type.'.label');
1585 foreach($tbl as $dn => $dn_name) {
1586 $LSaccess[$dn]=$access;
1595 if ((isCompatibleDNs(self :: $ldapServer['ldap_config']['basedn'],$config['dn']))&&($config['dn']!='')) {
1597 if (is_array($config['LSobjects'])) {
1598 foreach($config['LSobjects'] as $objectType) {
1599 if (self :: loadLSobject($objectType)) {
1600 if (self :: canAccess($objectType)) {
1601 $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label');
1606 $LSaccess[$config['dn']]=$access;
1612 if(is_array(self :: $ldapServer['LSaccess'])) {
1614 foreach(self :: $ldapServer['LSaccess'] as $objectType) {
1615 if (self :: loadLSobject($objectType)) {
1616 if (self :: canAccess($objectType)) {
1617 $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label');
1621 $LSaccess[self :: $topDn] = $access;
1624 if (LSauth :: displaySelfAccess()) {
1625 foreach($LSaccess as $dn => $access) {
1626 $LSaccess[$dn] = array_merge(
1628 'SELF' => 'My account'
1634 self :: $LSaccess = $LSaccess;
1635 $_SESSION['LSsession']['LSaccess'] = $LSaccess;
1639 * Dit si l'utilisateur est du profil pour le DN spécifié
1641 * @param[in] string $profile de l'objet
1642 * @param[in] string $dn DN de l'objet
1644 * @retval boolean True si l'utilisateur est du profil sur l'objet, false sinon.
1646 public static function isLSprofile($dn,$profile) {
1647 if (is_array(self :: $LSprofiles[$profile])) {
1648 foreach(self :: $LSprofiles[$profile] as $topDn) {
1652 else if ( isCompatibleDNs($dn,$topDn) ) {
1661 * Retourne qui est l'utilisateur par rapport à l'object
1663 * @param[in] string Le DN de l'objet
1665 * @retval string 'admin'/'self'/'user' pour Admin , l'utilisateur lui même ou un simple utilisateur
1667 public static function whoami($dn) {
1668 $retval = array('user');
1670 foreach(self :: $LSprofiles as $profile => $infos) {
1671 if(self :: isLSprofile($dn,$profile)) {
1676 if (self :: $dn == $dn) {
1684 * Retourne le droit de l'utilisateur à accèder à un objet
1686 * @param[in] string $LSobject Le type de l'objet
1687 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1688 * @param[in] string $right Le type de droit d'accès à tester ('r'/'w')
1689 * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1691 * @retval boolean True si l'utilisateur a accès, false sinon
1693 public static function canAccess($LSobject,$dn=NULL,$right=NULL,$attr=NULL) {
1694 if (!self :: loadLSobject($LSobject)) {
1698 $whoami = self :: whoami($dn);
1699 if ($dn==self :: getLSuserObject() -> getValue('dn')) {
1700 if (!self :: in_menu('SELF')) {
1705 $obj = new $LSobject();
1707 if (!self :: in_menu($LSobject,$obj -> subDnValue)) {
1713 $objectdn=LSconfig :: get('LSobjects.'.$LSobject.'.container_dn').','.self :: $topDn;
1714 $whoami = self :: whoami($objectdn);
1717 // Pour un attribut particulier
1720 $attr=LSconfig :: get('LSobjects.'.$LSobject.'.rdn');
1722 if (!is_array(LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr))) {
1727 foreach($whoami as $who) {
1728 $nr = LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr.'.rights.'.$who);
1732 else if($nr == 'r') {
1739 if (($right=='r')||($right=='w')) {
1746 if ( ($r=='r') || ($r=='w') ) {
1753 // Pour un attribut quelconque
1754 $attrs_conf=LSconfig :: get('LSobjects.'.$LSobject.'.attrs');
1755 if (is_array($attrs_conf)) {
1756 if (($right=='r')||($right=='w')) {
1757 foreach($whoami as $who) {
1758 foreach ($attrs_conf as $attr_name => $attr_config) {
1759 if (isset($attr_config['rights'][$who]) && $attr_config['rights'][$who]==$right) {
1766 foreach($whoami as $who) {
1767 foreach ($attrs_conf as $attr_name => $attr_config) {
1768 if ( (isset($attr_config['rights'][$who])) && ( ($attr_config['rights'][$who]=='r') || ($attr_config['rights'][$who]=='w') ) ) {
1779 * Retourne le droit de l'utilisateur à editer à un objet
1781 * @param[in] string $LSobject Le type de l'objet
1782 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1783 * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1785 * @retval boolean True si l'utilisateur a accès, false sinon
1787 public static function canEdit($LSobject,$dn=NULL,$attr=NULL) {
1788 return self :: canAccess($LSobject,$dn,'w',$attr);
1792 * Retourne le droit de l'utilisateur à supprimer un objet
1794 * @param[in] string $LSobject Le type de l'objet
1795 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1797 * @retval boolean True si l'utilisateur a accès, false sinon
1799 public static function canRemove($LSobject,$dn) {
1800 return self :: canAccess($LSobject,$dn,'w','rdn');
1804 * Retourne le droit de l'utilisateur à créer un objet
1806 * @param[in] string $LSobject Le type de l'objet
1808 * @retval boolean True si l'utilisateur a accès, false sinon
1810 public static function canCreate($LSobject) {
1811 if (!self :: loadLSobject($LSobject)) {
1814 if (LSconfig :: get("LSobjects.$LSobject.disable_creation")) {
1817 return self :: canAccess($LSobject,NULL,'w','rdn');
1821 * Retourne le droit de l'utilisateur à gérer la relation d'objet
1823 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1824 * @param[in] string $LSobject Le type de l'objet
1825 * @param[in] string $relationName Le nom de la relation avec l'objet
1826 * @param[in] string $right Le type de droit a vérifier ('r' ou 'w')
1828 * @retval boolean True si l'utilisateur a accès, false sinon
1830 public static function relationCanAccess($dn,$LSobject,$relationName,$right=NULL) {
1831 $relConf=LSconfig :: get('LSobjects.'.$LSobject.'.LSrelation.'.$relationName);
1832 if (!is_array($relConf))
1834 $whoami = self :: whoami($dn);
1836 if (($right=='w') || ($right=='r')) {
1838 foreach($whoami as $who) {
1839 $nr = ((isset($relConf['rights'][$who]))?$relConf['rights'][$who]:'');
1843 else if($nr == 'r') {
1855 foreach($whoami as $who) {
1856 if ((isset($relConf['rights'][$who])) && ( ($relConf['rights'][$who] == 'w') || ($relConf['rights'][$who] == 'r') ) ) {
1865 * Retourne le droit de l'utilisateur à modifier la relation d'objet
1867 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1868 * @param[in] string $LSobject Le type de l'objet
1869 * @param[in] string $relationName Le nom de la relation avec l'objet
1871 * @retval boolean True si l'utilisateur a accès, false sinon
1873 public static function relationCanEdit($dn,$LSobject,$relationName) {
1874 return self :: relationCanAccess($dn,$LSobject,$relationName,'w');
1878 * Retourne le droit de l'utilisateur a executer une customAction
1880 * @param[in] string $dn Le DN de l'objet
1881 * @param[in] string $LSobject Le type de l'objet
1882 * @param[in] string $customActionName Le nom de la customAction
1884 * @retval boolean True si l'utilisateur peut executer cette customAction, false sinon
1886 public static function canExecuteCustomAction($dn,$LSobject,$customActionName) {
1887 $conf=LSconfig :: get('LSobjects.'.$LSobject.'.customActions.'.$customActionName);
1888 if (!is_array($conf))
1890 $whoami = self :: whoami($dn);
1892 if (isset($conf['rights']) && is_array($conf['rights'])) {
1893 foreach($whoami as $who) {
1894 if (in_array($who,$conf['rights'])) {
1904 * Ajoute un fichier temporaire
1906 * @author Benjamin Renard <brenard@easter-eggs.com>
1910 public static function addTmpFile($value,$filePath) {
1911 $hash = mhash(MHASH_MD5,$value);
1912 self :: $tmp_file[$filePath] = $hash;
1913 $_SESSION['LSsession']['tmp_file'][$filePath] = $hash;
1917 * Retourne le chemin du fichier temporaire si l'existe
1919 * @author Benjamin Renard <brenard@easter-eggs.com>
1921 * @param[in] $value La valeur du fichier
1925 public static function tmpFileExist($value) {
1926 $hash = mhash(MHASH_MD5,$value);
1927 foreach(self :: $tmp_file as $filePath => $contentHash) {
1928 if ($hash == $contentHash) {
1936 * Retourne le chemin du fichier temporaire
1938 * Retourne le chemin du fichier temporaire qu'il créera à partir de la valeur
1939 * s'il n'existe pas déjà .
1941 * @author Benjamin Renard <brenard@easter-eggs.com>
1943 * @param[in] $value La valeur du fichier
1947 public static function getTmpFile($value) {
1948 $exist = self :: tmpFileExist($value);
1950 $img_path = LS_TMP_DIR .rand().'.tmp';
1951 $fp = fopen($img_path, "w");
1952 fwrite($fp, $value);
1954 self :: addTmpFile($value,$img_path);
1963 * Supprime les fichiers temporaires
1965 * @author Benjamin Renard <brenard@easter-eggs.com>
1969 public static function deleteTmpFile($filePath=NULL) {
1972 unset(self :: $tmp_file[$filePath]);
1973 unset($_SESSION['LSsession']['tmp_file'][$filePath]);
1976 foreach(self :: $tmp_file as $file => $content) {
1979 self :: $tmp_file = array();
1980 $_SESSION['LSsession']['tmp_file'] = array();
1985 * Retourne true si le cache des droits est activé
1987 * @author Benjamin Renard <brenard@easter-eggs.com>
1989 * @retval boolean True si le cache des droits est activé, false sinon.
1991 public static function cacheLSprofiles() {
1992 return ( (LSconfig :: get('cacheLSprofiles')) || (self :: $ldapServer['cacheLSprofiles']) );
1996 * Retourne true si le cache des subDn est activé
1998 * @author Benjamin Renard <brenard@easter-eggs.com>
2000 * @retval boolean True si le cache des subDn est activé, false sinon.
2002 public static function cacheSudDn() {
2003 return ( (LSconfig :: get('cacheSubDn')) || (self :: $ldapServer['cacheSubDn']));
2007 * Retourne true si le cache des recherches est activé
2009 * @author Benjamin Renard <brenard@easter-eggs.com>
2011 * @retval boolean True si le cache des recherches est activé, false sinon.
2013 public static function cacheSearch() {
2014 return ( (LSconfig :: get('cacheSearch')) || (self :: $ldapServer['cacheSearch']));
2018 * Retourne le label des niveaux pour le serveur ldap courant
2020 * @author Benjamin Renard <brenard@easter-eggs.com>
2022 * @retval string Le label des niveaux pour le serveur ldap dourant
2024 public static function getSubDnLabel() {
2025 return (self :: $ldapServer['subDnLabel']!='')?__(self :: $ldapServer['subDnLabel']):_('Level');
2029 * Retourne le nom du subDn
2031 * @param[in] $subDn string subDn
2033 * @retval string Le nom du subDn ou '' sinon
2035 public static function getSubDnName($subDn=false) {
2037 $subDn = self :: $topDn;
2039 if (self :: getSubDnLdapServer(false)) {
2040 if (isset(self :: $_subDnLdapServer[self :: $ldapServerId][false][$subDn])) {
2041 return self :: $_subDnLdapServer[self :: $ldapServerId][false][$subDn];
2048 * L'objet est t-il utilisé pour listé les subDnS
2050 * @param[in] $type string Le type d'objet
2052 * @retval boolean true si le type d'objet est un subDnObject, false sinon
2054 public static function isSubDnLSobject($type) {
2056 if (isset(self :: $ldapServer['subDn']['LSobject']) && is_array(self :: $ldapServer['subDn']['LSobject'])) {
2057 foreach(self :: $ldapServer['subDn']['LSobject'] as $key => $value) {
2067 * Indique si un type d'objet est dans le menu courant
2069 * @retval boolean true si le type d'objet est dans le menu, false sinon
2071 public static function in_menu($LSobject,$topDn=NULL) {
2073 $topDn=self :: $topDn;
2075 return isset(self :: $LSaccess[$topDn][$LSobject]);
2079 * Indique si le serveur LDAP courant a des subDn
2081 * @retval boolean true si le serveur LDAP courant a des subDn, false sinon
2083 public static function haveSubDn() {
2084 return (isset(self :: $ldapServer['subDn']) && is_array(self :: $ldapServer['subDn']));
2088 * Ajoute une information à afficher
2090 * @param[in] $msg string Le message à afficher
2094 public static function addInfo($msg) {
2095 $_SESSION['LSsession_infos'][]=$msg;
2099 * Redirection de l'utilisateur vers une autre URL
2101 * @param[in] $url string L'URL
2102 * @param[in] $exit boolean Si true, l'execution script s'arrête après la redirection
2106 public static function redirect($url,$exit=true) {
2107 LStemplate :: assign('url',$url);
2108 LStemplate :: display('redirect.tpl');
2115 * Retourne l'adresse mail d'emission configurée pour le serveur courant
2117 * @retval string Adresse mail d'emission
2119 public static function getEmailSender() {
2120 return self :: $ldapServer['emailSender'];
2124 * Ajout d'une information d'aide
2126 * @param[in] $group string Le nom du groupe d'infos dans lequels ajouter
2128 * @param[in] $infos array Tableau array(name => value) des infos
2132 public static function addHelpInfos($group,$infos) {
2133 if (is_array($infos)) {
2134 if (isset(self :: $_JSconfigParams['helpInfos'][$group]) && is_array(self :: $_JSconfigParams['helpInfos'][$group])) {
2135 self :: $_JSconfigParams['helpInfos'][$group] = array_merge(self :: $_JSconfigParams['helpInfos'][$group],$infos);
2138 self :: $_JSconfigParams['helpInfos'][$group] = $infos;
2144 * Défini les codes erreur relative à la classe LSsession
2148 private static function defineLSerrors() {
2152 LSerror :: defineError('LSsession_01',
2153 _("LSsession : The constant %{const} is not defined.")
2155 LSerror :: defineError('LSsession_02',
2156 _("LSsession : The %{addon} support is uncertain. Verify system compatibility and the add-on configuration.")
2158 LSerror :: defineError('LSsession_03',
2159 _("LSsession : LDAP server's configuration data are invalid. Can't connect.")
2161 LSerror :: defineError('LSsession_04',
2162 _("LSsession : Failed to load LSobject type %{type} : unknon type.")
2164 LSerror :: defineError('LSsession_05',
2165 _("LSsession : Failed to load LSclass %{class}.")
2167 LSerror :: defineError('LSsession_06',
2168 _("LSsession : Login or password incorrect.")
2170 LSerror :: defineError('LSsession_07',
2171 _("LSsession : Impossible to identify you : Duplication of identities.")
2173 LSerror :: defineError('LSsession_08',
2174 _("LSsession : Can't load class of authentification (%{class}).")
2176 LSerror :: defineError('LSsession_09',
2177 _("LSsession : Can't connect to LDAP server.")
2179 LSerror :: defineError('LSsession_10',
2180 _("LSsession : Impossible to authenticate you.")
2182 LSerror :: defineError('LSsession_11',
2183 _("LSsession : Your are not authorized to do this action.")
2185 LSerror :: defineError('LSsession_12',
2186 _("LSsession : Some informations are missing to display this page.")
2188 LSerror :: defineError('LSsession_13',
2189 _("LSsession : The function of the custom action %{name} does not exists or is not configured.")
2191 // 14 -> 16 : not yet used
2192 LSerror :: defineError('LSsession_17',
2193 _("LSsession : Error during creation of list of levels. Contact administrators. (Code : %{code})")
2195 LSerror :: defineError('LSsession_18',
2196 _("LSsession : The password recovery is disabled for this LDAP server.")
2198 LSerror :: defineError('LSsession_19',
2199 _("LSsession : Some informations are missing to recover your password. Contact administrators.")
2201 LSerror :: defineError('LSsession_20',
2202 _("LSsession : Error during password recovery. Contact administrators.(Step : %{step})")
2204 // 21 : not yet used
2205 LSerror :: defineError('LSsession_22',
2206 _("LSsession : problem during initialisation.")
2211 * Ajax method when change ldapserver on login form
2213 * @param[in] $data array The return data address
2217 public static function ajax_onLdapServerChangedLogin(&$data) {
2218 if ( isset($_REQUEST['server']) ) {
2219 self :: setLdapServer($_REQUEST['server']);
2221 if ( self :: LSldapConnect() ) {
2222 if (session_id()=="") session_start();
2223 if (isset($_SESSION['LSsession_topDn'])) {
2224 $sel = $_SESSION['LSsession_topDn'];
2229 $list = self :: getSubDnLdapServerOptions($sel,true);
2230 if (is_string($list)) {
2231 $data['list_topDn'] = "<select name='LSsession_topDn' id='LSsession_topDn'>".$list."</select>";
2232 $data['subDnLabel'] = self :: getSubDnLabel();
2235 $data['recoverPassword'] = isset(self :: $ldapServer['recoverPassword']);
2240 * Ajax method when change ldapserver on recoverPassword form
2242 * @param[in] $data array The return data address
2246 public static function ajax_onLdapServerChangedRecoverPassword(&$data) {
2247 if ( isset($_REQUEST['server']) ) {
2248 self :: setLdapServer($_REQUEST['server']);
2249 $data=array('recoverPassword' => isset(self :: $ldapServer['recoverPassword']));