LSsession :: includeFile() : Fixed Notice PHP
[ldapsaisie.git] / public_html / includes / class / class.LSsession.php
1 <?php
2 /*******************************************************************************
3  * Copyright (C) 2007 Easter-eggs
4  * http://ldapsaisie.labs.libre-entreprise.org
5  *
6  * Author: See AUTHORS file in top-level directory.
7  *
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.
11  *
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.
16  *
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.
20
21 ******************************************************************************/
22
23 /** 
24  * Gestion des sessions
25  *
26  * Cette classe gère les sessions d'utilisateurs.
27  *
28  * @author Benjamin Renard <brenard@easter-eggs.com>
29  */
30 class LSsession {
31
32   // La configuration du serveur Ldap utilisé
33   public static $ldapServer = NULL;
34   
35   // L'id du serveur Ldap utilisé
36   private static $ldapServerId = NULL;
37   
38   // Le topDn courant
39   private static $topDn = NULL;
40   
41   // Le DN de l'utilisateur connecté
42   private static $dn = NULL;
43   
44   // Le RDN de l'utilisateur connecté (son identifiant)
45   private static $rdn = NULL;
46   
47   // Les LSprofiles de l'utilisateur
48   private static $LSprofiles = array();
49   
50   // Les droits d'accès de l'utilisateur
51   private static $LSaccess = array();
52   
53   // Authentification parameters
54   private static $authParams = array();
55   
56   // Les fichiers temporaires
57   private static $tmp_file = array();
58   
59   // Langue et encodage actuel
60   private static $lang = NULL;
61   private static $encoding = NULL;
62   
63   /*
64    * Constante de classe non stockée en session
65    */
66   // Le template à afficher
67   private static $template = NULL;
68   
69   // Les subDn des serveurs Ldap
70   private static $_subDnLdapServer = array();
71   
72   // Affichage Ajax
73   private static $ajaxDisplay = false;
74
75   // Les fichiers JS à charger dans la page
76   private static $JSscripts = array();
77   
78   // Les paramètres JS à communiquer dans la page
79   private static $_JSconfigParams = array();
80   
81   // Les fichiers CSS à charger dans la page
82   private static $CssFiles = array();
83
84   // L'objet de l'utilisateur connecté
85   private static $LSuserObject = NULL;
86   
87   // The LSauht object of the session
88   private static $LSauthObject = false;
89
90  /**
91   * Include un fichier PHP
92   *
93   * @author Benjamin Renard <brenard@easter-eggs.com>
94   *
95   * @retval true si tout c'est bien passé, false sinon
96   */
97   public static function includeFile($file) {
98     if (!file_exists($file)) {
99       return;
100     }
101     if (defined('LSdebug') && constant('LSdebug')) {
102       return include_once($file);
103     }
104     else {
105       return @include_once($file);
106     }
107     return;
108   }
109
110  /**
111   * Lancement de LSconfig
112   *
113   * @author Benjamin Renard <brenard@easter-eggs.com>
114   *
115   * @retval true si tout c'est bien passé, false sinon
116   */
117   private static function startLSconfig() {
118     if (self :: loadLSclass('LSconfig')) {
119       if (LSconfig :: start()) {
120         return true;
121       }
122     }
123     die("ERROR : Can't load configuration files.");
124     return;
125   }
126
127  /**
128   * Lancement et initialisation de Smarty
129   *
130   * @author Benjamin Renard <brenard@easter-eggs.com>
131   *
132   * @retval true si tout c'est bien passé, false sinon
133   */  
134   private static function startLStemplate() {
135     if ( self :: includeFile(LSconfig :: get('Smarty')) ) {
136       $GLOBALS['Smarty'] = new Smarty();
137       $GLOBALS['Smarty'] -> template_dir = LS_TEMPLATES_DIR;
138       $GLOBALS['Smarty'] -> compile_dir = LS_TMP_DIR;
139       
140       if (LSdebug) {
141         $GLOBALS['Smarty'] -> caching = 0;
142         // cache files are always regenerated
143         $GLOBALS['Smarty'] -> force_compile = TRUE;
144         // recompile template if it is changed
145         $GLOBALS['Smarty'] -> compile_check = TRUE;
146         if (isset($_REQUEST['debug_smarty'])) {
147           // debug smarty
148           $GLOBALS['Smarty'] -> debugging = true; 
149         }
150       }
151       
152       $GLOBALS['Smarty'] -> assign('LS_CSS_DIR',LS_CSS_DIR);
153       $GLOBALS['Smarty'] -> assign('LS_IMAGES_DIR',LS_IMAGES_DIR);
154       
155       self :: addJSconfigParam('LS_IMAGES_DIR',LS_IMAGES_DIR);
156       return true;
157     }
158     die("ERROR : Can't load Smarty.");
159     return;
160   }
161   
162  /**
163   * Retourne le topDn de la session
164   *
165   * @author Benjamin Renard <brenard@easter-eggs.com>
166   *
167   * @retval string le topDn de la session
168   */
169   public static function getTopDn() {
170     if (!is_null(self :: $topDn)) {
171       return self :: $topDn;
172     }
173     else {
174       return self :: getRootDn();
175     }
176   }
177   
178  /**
179   * Retourne le rootDn de la session
180   *
181   * @author Benjamin Renard <brenard@easter-eggs.com>
182   *
183   * @retval string le rootDn de la session
184   */
185   public static function getRootDn() {
186     return self :: $ldapServer['ldap_config']['basedn'];
187   }
188
189  /**
190   * Initialisation de la gestion des erreurs
191   *
192   * Création de l'objet LSerror
193   *
194   * @author Benjamin Renard <brenard@easter-eggs.com
195   *
196   * @retval boolean true si l'initialisation a réussi, false sinon.
197   */
198   private static function startLSerror() {
199     if(!self :: loadLSclass('LSerror')) {
200       return;
201     }
202     self :: defineLSerrors();
203     return true;
204   }
205
206  /**
207   * Chargement d'une classe d'LdapSaisie
208   *
209   * @param[in] $class Nom de la classe Ã  charger (Exemple : LSpeople)
210   * @param[in] $type (Optionnel) Type de classe Ã  charger (Exemple : LSobjects)
211   *
212   * @author Benjamin Renard <brenard@easter-eggs.com
213   * 
214   * @retval boolean true si le chargement a réussi, false sinon.
215   */
216   public static function loadLSclass($class,$type='') {
217     if (class_exists($class))
218       return true;
219     if($type!='')
220       $type=$type.'.';
221     return self :: includeFile(LS_CLASS_DIR .'class.'.$type.$class.'.php');
222   }
223
224  /**
225   * Chargement d'un object LdapSaisie
226   *
227   * @param[in] $object Nom de l'objet Ã  charger
228   *
229   * @retval boolean true si le chargement a réussi, false sinon.
230   */
231   public static function loadLSobject($object) {
232     if(class_exists($object)) {
233       return true;
234     }
235     $error = 0;
236     self :: loadLSclass('LSldapObject');
237     if (!self :: loadLSclass($object,'LSobjects')) {
238       $error = 1;
239     }
240     if (!self :: includeFile( LS_OBJECTS_DIR . 'config.LSobjects.'.$object.'.php' )) {
241       $error = 1;
242     }
243     else {
244       if (!LSconfig :: set("LSobjects.$object",$GLOBALS['LSobjects'][$object])) {
245         $error = 1;
246       }
247       else if (isset($GLOBALS['LSobjects'][$object]['LSaddons'])){
248         if (is_array($GLOBALS['LSobjects'][$object]['LSaddons'])) {
249           foreach ($GLOBALS['LSobjects'][$object]['LSaddons'] as $addon) {
250             if (!self :: loadLSaddon($addon)) {
251               $error = 1;
252             }
253           }
254         }
255         else {
256           if (!self :: loadLSaddon($GLOBALS['LSobjects'][$object]['LSaddons'])) {
257             $error = 1;
258           }
259         } 
260       }
261     }
262     if ($error) {
263       LSerror :: addErrorCode('LSsession_04',$object);
264       return;
265     }
266     return true;
267   }
268
269  /**
270   * Chargement d'un addons d'LdapSaisie
271   *
272   * @param[in] $addon Nom de l'addon Ã  charger (Exemple : samba)
273   *
274   * @author Benjamin Renard <brenard@easter-eggs.com
275   * 
276   * @retval boolean true si le chargement a réussi, false sinon.
277   */
278   public static function loadLSaddon($addon) {
279     if(self :: includeFile(LS_ADDONS_DIR .'LSaddons.'.$addon.'.php')) {
280       self :: includeFile(LS_CONF_DIR."LSaddons/config.LSaddons.".$addon.".php");
281       if (!call_user_func('LSaddon_'. $addon .'_support')) {
282         LSerror :: addErrorCode('LSsession_02',$addon);
283         return;
284       }
285       return true;
286     }
287     return;
288   }
289
290  /**
291   * Chargement d'une classe d'authentification d'LdapSaisie
292   *
293   * @param[in] $auth Nom de la classe d'authentification a charger (Exemple : HTTP)
294   *
295   * @author Benjamin Renard <brenard@easter-eggs.com
296   * 
297   * @retval boolean true si le chargement a reussi, false sinon.
298   */
299   public static function loadLSauth($auth=false) {
300     if (self :: loadLSclass('LSauth')) {
301       if ($auth) {
302         if(self :: includeFile(LS_CLASS_DIR .'class.LSauth'.$auth.'.php')) {
303           self :: includeFile(LS_CONF_DIR."LSauth/config.LSauth".$auth.".php");
304           return true;
305         }
306       }
307       else {
308         return true;
309       } 
310     }
311     else {
312       LSerror :: addErrorCode('LSsession_05','LSauth');
313     }
314     return;
315   }
316
317  /**
318   * Chargement des addons LdapSaisie
319   *
320   * Chargement des LSaddons contenue dans la variable
321   * $GLOBALS['LSaddons']['loads']
322   *
323   * @retval boolean true si le chargement a réussi, false sinon.
324   */
325   public static function loadLSaddons() {
326     $conf=LSconfig :: get('LSaddons.loads');
327     if(!is_array($conf)) {
328       LSerror :: addErrorCode('LSsession_01',"LSaddons['loads']");
329       return;
330     }
331
332     foreach ($conf as $addon) {
333       self :: loadLSaddon($addon);
334     }
335     return true;
336   }
337
338  /**
339   * Défini la locale
340   * 
341   * @retval void
342   */
343   public static function setLocale() {
344     if (isset($_REQUEST['lang'])) {
345       $lang = $_REQUEST['lang'];
346     }
347     elseif (isset($_SESSION['LSlang'])) {
348       $lang = $_SESSION['LSlang'];
349     }
350     elseif (isset(self :: $ldapServer['lang'])) {
351       $lang = self :: $ldapServer['lang'];
352     }
353     else {
354       $lang = LSconfig :: get('lang');
355     }
356     
357     if (isset($_REQUEST['encoding'])) {
358       $encoding = $_REQUEST['encoding'];
359     }
360     elseif (isset($_SESSION['LSencoding'])) {
361       $encoding = $_SESSION['LSencoding'];
362     }
363     elseif (isset(self :: $ldapServer['encoding'])) {
364       $encoding = self :: $ldapServer['encoding'];
365     }
366     else {
367       $encoding = LSconfig :: get('encoding');
368     }
369     
370     $_SESSION['LSlang']=$lang;
371     self :: $lang=$lang;
372     $_SESSION['LSencoding']=$encoding;
373     self :: $encoding=$encoding;
374     
375
376     if (self :: localeExist($lang,$encoding)) {
377       if ($encoding) {
378         $lang.='.'.$encoding;
379       }
380       setlocale(LC_ALL, $lang);
381       bindtextdomain(LS_TEXT_DOMAIN, LS_I18N_DIR);
382       textdomain(LS_TEXT_DOMAIN);
383       
384       if (is_file(LS_I18N_DIR.'/'.$lang.'/lang.php')) {
385         include(LS_I18N_DIR.'/'.$lang.'/lang.php');
386       }
387     }
388     else {
389       if ($encoding && $lang) {
390         $lang.='.'.$encoding;
391       }
392       LSdebug('La locale "'.$lang.'" n\'existe pas, utilisation de la locale par défaut.');
393     }
394   }
395   
396  /**
397   * Retourne la liste des langues disponibles
398   * 
399   * @retval array Tableau/Liste des langues disponibles
400   **/ 
401   public static function getLangList() {
402     $list=array('en_US');
403     if (self :: $encoding) {
404       $regex = '^([a-zA-Z_]*)\.'.self :: $encoding.'$';
405     }
406     else {
407       $regex = '^([a-zA-Z_]*)$';
408     }
409     if ($handle = opendir(LS_I18N_DIR)) {
410       while (false !== ($file = readdir($handle))) {
411         if(is_dir(LS_I18N_DIR.'/'.$file)) {
412           if (ereg($regex,$file,$regs)) {
413             if (!in_array($regs[1],$list)) {
414               $list[]=$regs[1];
415             }
416           }
417         }
418       }
419     }
420     return $list;
421   }
422
423  /**
424   * Retourne la langue courante de la session
425   * 
426   * @param[in] boolean Si true, le code langue retourné sera court
427   * 
428   * @retval string La langue de la session
429   **/
430   public static function getLang($short=false) {
431     if ($short) {
432       return strtolower(self :: $lang[0].self :: $lang[1]);
433     }
434     return self :: $lang;
435   }
436   
437  /**
438   * Vérifie si une locale est disponible
439   * 
440   * @param[in] $lang string La langue (Ex : fr_FR)
441   * @param[in] $encoding string L'encodage de caractère (Ex : UTF8)
442   * 
443   * @retval boolean True si la locale est disponible, False sinon
444   **/
445   public static function localeExist($lang,$encoding) {
446     if ( !$lang && !$encoding ) {
447       return;
448     }
449     $locale=$lang.(($encoding)?'.'.$encoding:'');
450     if ($locale=='en_US.UTF8') {
451       return true;
452     }
453     return (is_dir(LS_I18N_DIR.'/'.$locale));
454   }
455
456  /**
457   * Initialisation LdapSaisie
458   *
459   * @retval boolean True si l'initialisation à réussi, false sinon.
460   */
461   public static function initialize() {
462     if (!self :: startLSconfig()) {
463       return;
464     }
465     
466     self :: startLStemplate();
467     
468     session_start();
469     
470     self :: setLocale();
471     
472     self :: startLSerror();
473     self :: loadLSaddons();
474     return true;
475   }
476
477  /**
478   * Initialisation de la session LdapSaisie
479   *
480   * Initialisation d'une LSsession :
481   * - Authentification et activation du mécanisme de session de LdapSaisie
482   * - ou Chargement des paramètres de la session Ã  partir de la variable 
483   *   $_SESSION['LSsession'].
484   * - ou Destruction de la session en cas de $_GET['LSsession_logout'].
485   *
486   * @retval boolean True si l'initialisation Ã  réussi (utilisateur authentifié), false sinon.
487   */
488   public static function startLSsession() {
489     if (!self :: initialize()) {
490       return;
491     }
492     
493     if(isset($_SESSION['LSsession']['dn']) && !isset($_GET['LSsession_recoverPassword'])) {
494       // Session existante
495       self :: $topDn        = $_SESSION['LSsession']['topDn'];
496       self :: $dn           = $_SESSION['LSsession']['dn'];
497       self :: $rdn          = $_SESSION['LSsession']['rdn'];
498       self :: $ldapServerId = $_SESSION['LSsession']['ldapServerId'];
499       self :: $tmp_file     = $_SESSION['LSsession']['tmp_file'];
500       self :: $authParams   = $_SESSION['LSsession']['authParams'];
501       
502       if ( self :: cacheLSprofiles() && !isset($_REQUEST['LSsession_refresh']) ) {
503         self :: setLdapServer(self :: $ldapServerId);
504         self :: $LSprofiles   = $_SESSION['LSsession']['LSprofiles'];
505         self :: $LSaccess   = $_SESSION['LSsession']['LSaccess'];
506         if (!self :: LSldapConnect())
507           return;
508       }
509       else {
510         self :: setLdapServer(self :: $ldapServerId);
511         if (!self :: LSldapConnect())
512           return;
513         self :: loadLSprofiles();
514       }
515       
516       if ( self :: cacheSudDn() && (!isset($_REQUEST['LSsession_refresh'])) ) {
517         self :: $_subDnLdapServer = $_SESSION['LSsession_subDnLdapServer'];
518       }
519       
520       if (!self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
521         return;
522       }
523       
524       if (isset($_GET['LSsession_logout'])) {
525         $authObj = self :: getLSauthObject();
526         if ($authObj) {
527           $authObj -> logout();
528         }
529         session_destroy();
530         
531         if (is_array($_SESSION['LSsession']['tmp_file'])) {
532           self :: $tmp_file = $_SESSION['LSsession']['tmp_file'];
533         }
534         self :: deleteTmpFile();
535         unset($_SESSION['LSsession']);
536         
537         self :: redirect('index.php');
538         return;
539       }
540       
541       self :: getLSuserObject();
542       
543       if ( !self :: cacheLSprofiles() || isset($_REQUEST['LSsession_refresh']) ) {
544         self :: loadLSaccess();
545       }
546       
547       $GLOBALS['Smarty'] -> assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
548       
549       if ($_POST['LSsession_topDn']) {
550         if (self :: validSubDnLdapServer($_POST['LSsession_topDn'])) {
551           self :: $topDn = $_POST['LSsession_topDn'];
552           $_SESSION['LSsession']['topDn'] = $_POST['LSsession_topDn'];
553         } // end if
554       } // end if
555       
556       return true;
557       
558     }
559     else {
560       if (isset($_GET['LSsession_recoverPassword'])) {
561         session_destroy();
562       }
563       // Session inexistante
564       if (isset($_POST['LSsession_ldapserver'])) {
565         self :: setLdapServer($_POST['LSsession_ldapserver']);
566       }
567       else {
568         self :: setLdapServer(0);
569       }
570       
571       // Connexion au serveur LDAP
572       if (self :: LSldapConnect()) {
573
574         // topDn
575         if ( $_POST['LSsession_topDn'] != '' ){
576           self :: $topDn = $_POST['LSsession_topDn'];
577         }
578         else {
579           self :: $topDn = self :: $ldapServer['ldap_config']['basedn'];
580         }
581         $_SESSION['LSsession_topDn']=self :: $topDn;
582
583         if (isset($_GET['LSsession_recoverPassword'])) {
584           $recoveryPasswordInfos = self :: recoverPasswd(
585                                       $_REQUEST['LSsession_user'],
586                                       $_GET['recoveryHash']
587                                    );
588         }
589         else {
590           $authObj=self :: getLSauthObject();
591           if ($authObj) {
592             if ($authObj -> getPostData()) {
593               $LSuserObject = $authObj -> authenticate();
594               if ($LSuserObject) {
595                 // Authentication successful
596                 self :: $LSuserObject = $LSuserObject;
597                 self :: $dn = $LSuserObject->getValue('dn');
598                 self :: $rdn = $LSuserObject->getValue('rdn');
599                 self :: loadLSprofiles();
600                 self :: loadLSaccess();
601                 $GLOBALS['Smarty'] -> assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
602                 $_SESSION['LSsession']=self :: getContextInfos();
603                 return true;
604               }
605             }
606           }
607         }
608       }
609       else {
610         LSerror :: addErrorCode('LSsession_09');
611       }
612       
613       if (self :: $ldapServerId) {
614         $GLOBALS['Smarty'] -> assign('ldapServerId',self :: $ldapServerId);
615       }
616       $GLOBALS['Smarty'] -> assign('topDn',self :: $topDn);
617       if (isset($_GET['LSsession_recoverPassword'])) {
618         self :: displayRecoverPasswordForm($recoveryPasswordInfos);
619       }
620       elseif(self :: $authParams['displayLoginForm']) {
621         self :: displayLoginForm();
622       }
623       else {
624         self :: setTemplate('blank.tpl');
625         LSerror :: addErrorCode('LSsession_10');
626       }
627       return;
628     }
629   }
630
631   /**
632    * Get LSauthObject
633    * 
634    * @retval LSauth object or false
635    **/
636   private static function getLSauthObject() {
637     if (!self :: $LSauthObject) {
638       if (self :: loadLSauth()) {
639         if (isset(self :: $ldapServer['LSauth']['method'])) {
640           $LSauthClass = 'LSauth'.self :: $ldapServer['LSauth']['method'];
641           if (!self :: loadLSauth(self :: $ldapServer['LSauth']['method'])) {
642             LSerror :: addErrorCode('LSsession_08',self :: $ldapServer['LSauth']['method']);
643             $LSauthClass = 'LSauth';
644           }
645         }
646         else {
647           $LSauthClass = 'LSauth';
648         }
649         
650         self :: $LSauthObject = new $LSauthClass();
651         self :: $authParams = self :: $LSauthObject->params;
652       }
653     }
654     return self :: $LSauthObject;
655   }     
656   
657   /**
658    * Do recover password
659    * 
660    * @param[in] $username string The submited username
661    * @param[in] $recoveryHash string The submited recoveryHash
662    * 
663    * @retval array The recoveryPassword infos for template
664    **/
665   private static function recoverPasswd($username,$recoveryHash) {
666     $recoveryPasswordInfos=array();
667     if ( self :: loadLSobject(self :: $ldapServer['authObjectType']) ) {
668       $authobject = new self :: $ldapServer['authObjectType']();
669       if (!empty($recoveryHash)) {
670         $filter=Net_LDAP2_Filter::create(
671           self :: $ldapServer['recoverPassword']['recoveryHashAttr'],
672           'equals',
673           $recoveryHash
674         );
675         $result = $authobject -> listObjects($filter,self :: $topDn);
676       }
677       elseif (!empty($username)) {
678         $result = $authobject -> searchObject(
679                     $username,
680                     self :: $topDn,
681                     self :: $ldapServer['authObjectFilter']
682                   );
683       }
684       else {
685         return $recoveryPasswordInfos;
686       }
687       
688       $nbresult=count($result);
689       
690       if ($nbresult==0) {
691         LSdebug('hash/username incorrect');
692         LSerror :: addErrorCode('LSsession_06');  
693       }
694       elseif ($nbresult>1) {
695         LSerror :: addErrorCode('LSsession_07');
696       }
697       else {
698         $rdn = $result[0] -> getValue('rdn');
699         $username = $rdn[0];
700         LSdebug('Recover : Id trouvé : '.$username);
701         if (self :: $ldapServer['recoverPassword']) {
702           if (self :: loadLSaddon('mail')) {
703             LSdebug('Récupération active');
704             $user=$result[0];
705             $emailAddress = $user -> getValue(self :: $ldapServer['recoverPassword']['mailAttr']);
706             $emailAddress = $emailAddress[0];
707             
708             if (checkEmail($emailAddress)) {
709               LSdebug('Email : '.$emailAddress);
710               self :: $dn = $user -> getDn();
711               
712               // 1ère étape : envoie du recoveryHash
713               if (empty($recoveryHash)) {
714                 $hash=self :: recoverPasswdFirstStep($user);
715                 if ($hash) {
716                   if (self :: recoverPasswdSendMail($emailAddress,1,$hash)) {
717                     // Mail a bien été envoyé
718                     $recoveryPasswordInfos['recoveryHashMail']=$emailAddress;
719                   }
720                 }
721               }
722               // 2nd étape : génération du mot de passe + envoie par mail
723               else {
724                 $pwd=self :: recoverPasswdSecondStep($user);
725                 if ($pwd) {
726                   if (self :: recoverPasswdSendMail($emailAddress,2,$pwd)){
727                     // Mail a bien été envoyé
728                     $recoveryPasswordInfos['newPasswordMail']=$emailAddress;
729                   }
730                 }
731               }
732             }
733             else {
734               LSerror :: addErrorCode('LSsession_19');
735             }
736           }
737         }
738         else {
739           LSerror :: addErrorCode('LSsession_18');
740         }
741       }
742     }
743     return $recoveryPasswordInfos;
744   }
745   
746   /**
747    * Send recover password mail
748    * 
749    * @param[in] $mail string The user's mail
750    * @param[in] $step integer The step
751    * @param[in] $info string The info for formatted message
752    * 
753    * @retval boolean True on success or False
754    **/
755   private static function recoverPasswdSendMail($mail,$step,$info) {
756     // Header des mails
757     $sendParams=array();
758     if (self :: $ldapServer['recoverPassword']['recoveryEmailSender']) {
759       $sendParams['From']=self :: $ldapServer['recoverPassword']['recoveryEmailSender'];
760     }
761     
762     if ($step==1) {
763       if ($_SERVER['HTTPS']=='on') {
764         $recovery_url='https://';
765       }
766       else {
767         $recovery_url='http://';
768       }
769       $recovery_url .= $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'&recoveryHash='.$info;
770       
771       $subject = self :: $ldapServer['recoverPassword']['recoveryHashMail']['subject'];
772       $msg = getFData(
773         self :: $ldapServer['recoverPassword']['recoveryHashMail']['msg'],
774         $recovery_url
775       );
776     }
777     else {
778       $subject = self :: $ldapServer['recoverPassword']['newPasswordMail']['subject'];
779       $msg = getFData(
780         self :: $ldapServer['recoverPassword']['newPasswordMail']['msg'],
781         $info
782       );
783     }
784     
785     if (!sendMail($mail,$subject,$msg,$sendParams)) {
786       LSdebug("Problème durant l'envoie du mail");
787       LSerror :: addErrorCode('LSsession_20',4);
788       return;
789     }
790     return true;
791   }
792   
793   
794   /**
795    * Do first step of recovering password
796    * 
797    * @param[in] $user LSldapObject The LSldapObject of the user
798    * 
799    * @retval string|False The recory hash on success or False
800    **/
801   private static function recoverPasswdFirstStep($user) {
802     // Generer un hash
803     $rdn=$user -> getValue('rdn');
804     $rdn = $rdn[0];
805     $recovery_hash = md5($rdn . strval(time()) . strval(rand()));
806     
807     $lostPasswdForm = $user -> getForm('lostPassword');
808     $lostPasswdForm -> setPostData(
809       array(
810         self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => $recovery_hash
811       )
812       ,true
813     );
814       
815     if($lostPasswdForm -> validate()) {
816       if ($user -> updateData('lostPassword')) {
817         // recoveryHash de l'utilisateur mis à jour
818         return $recovery_hash;
819       }
820       else {
821         // Erreur durant la mise à jour de l'objet
822         LSdebug("Erreur durant la mise à jour de l'objet");
823         LSerror :: addErrorCode('LSsession_20',6);
824       }
825     }
826     else {
827       // Erreur durant la validation du formulaire de modification de perte de password
828       LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
829       LSerror :: addErrorCode('LSsession_20',5);
830     }
831     return;
832   }
833
834   /**
835    * Do second step of recovering password
836    * 
837    * @param[in] $user LSldapObject The LSldapObject of the user
838    * 
839    * @retval string|False The new password on success or False
840    **/
841   private static function recoverPasswdSecondStep($user) {
842     $attr=$user -> attrs[self :: $ldapServer['authObjectTypeAttrPwd']];
843     if ($attr instanceof LSattribute) {
844       $mdp = generatePassword(
845        $attr -> config['html_options']['chars'],
846        $attr -> config['html_options']['lenght']
847       );
848       LSdebug('Nvx mpd : '.$mdp);
849       $lostPasswdForm = $user -> getForm('lostPassword');
850       $lostPasswdForm -> setPostData(
851         array(
852           self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => array(''),
853           self :: $ldapServer['authObjectTypeAttrPwd'] => array($mdp)
854         )
855         ,true
856       );
857       if($lostPasswdForm -> validate()) {
858         if ($user -> updateData('lostPassword')) {
859           return $mdp;
860         }
861         else {
862           // Erreur durant la mise à jour de l'objet
863           LSdebug("Erreur durant la mise à jour de l'objet");
864           LSerror :: addErrorCode('LSsession_20',3);
865         }
866       }
867       else {
868         // Erreur durant la validation du formulaire de modification de perte de password
869         LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
870         LSerror :: addErrorCode('LSsession_20',2);
871       }
872     }
873     else {
874       // l'attribut password n'existe pas
875       LSdebug("L'attribut password n'existe pas");
876       LSerror :: addErrorCode('LSsession_20',1);
877     }
878     return;
879   }
880   
881  /**
882   * Retourne les informations du contexte
883   *
884   * @author Benjamin Renard <brenard@easter-eggs.com
885   * 
886   * @retval array Tableau associatif des informations du contexte
887   */
888   private static function getContextInfos() {
889     return array(
890       'tmp_file' => self :: $tmp_file,
891       'topDn' => self :: $topDn,
892       'dn' => self :: $dn,
893       'rdn' => self :: $rdn,
894       'ldapServerId' => self :: $ldapServerId,
895       'ldapServer' => self :: $ldapServer,
896       'LSprofiles' => self :: $LSprofiles,
897       'LSaccess' => self :: $LSaccess,
898       'authParams' => self :: $authParams
899     );
900   }
901   
902   /**
903   * Retourne l'objet de l'utilisateur connecté
904   *
905   * @author Benjamin Renard <brenard@easter-eggs.com
906   * 
907   * @retval mixed L'objet de l'utilisateur connecté ou false si il n'a pas put
908   *               être créé
909   */
910   public static function getLSuserObject($dn=null) {
911     if ($dn) {
912       self :: $dn = $dn;
913     }
914     if (!self :: $LSuserObject) {
915       if (self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
916         self :: $LSuserObject = new self :: $ldapServer['authObjectType']();
917         self :: $LSuserObject -> loadData(self :: $dn);
918       }
919       else {
920         return;
921       }
922     }
923     return self :: $LSuserObject;
924   }
925   
926  /**
927   * Retourne le DN de l'utilisateur connecté
928   *
929   * @author Benjamin Renard <brenard@easter-eggs.com
930   * 
931   * @retval string Le DN de l'utilisateur connecté
932   */
933   public static function getLSuserObjectDn() {
934     return self :: $dn;
935   }
936
937  /**
938   * Modifie l'utilisateur connecté à la volé
939   * 
940   * @param[in] $object Mixed  L'objet Ldap du nouvel utilisateur
941   *                           le type doit correspondre à
942   *                           self :: $ldapServer['authObjectType']
943   * 
944   * @retval boolean True en cas de succès, false sinon
945   */
946  public static function changeAuthUser($object) {
947   if ($object instanceof self :: $ldapServer['authObjectType']) {
948     self :: $dn = $object -> getDn();
949     $rdn = $object -> getValue('rdn');
950     if(is_array($rdn)) {
951       $rdn = $rdn[0];
952     }
953     self :: $rdn = $rdn;
954     self :: $LSuserObject = $object;
955     
956     if(self :: loadLSprofiles()) {
957       self :: loadLSaccess();
958       $_SESSION['LSsession']=self :: getContextInfos();
959       return true;
960     }
961   }
962   return;
963  }
964
965  /**
966   * Définition du serveur Ldap de la session
967   *
968   * Définition du serveur Ldap de la session Ã  partir de son ID dans 
969   * le tableau LSconfig :: get('ldap_servers').
970   *
971   * @param[in] integer Index du serveur Ldap
972   *
973   * @retval boolean True sinon false.
974   */
975   public static function setLdapServer($id) {
976     $conf = LSconfig :: get("ldap_servers.$id");
977     if ( is_array($conf) ) {
978       self :: $ldapServerId = $id;
979       self :: $ldapServer = $conf;
980       self :: setLocale();
981       return true;
982     }
983     else {
984       return;
985     }
986   }
987
988  /**
989   * Connexion au serveur Ldap
990   *
991   * @retval boolean True sinon false.
992   */
993   public static function LSldapConnect() {
994     if (self :: $ldapServer) {
995       self :: includeFile(LSconfig :: get('NetLDAP2'));
996       if (!self :: loadLSclass('LSldap')) {
997         return;
998       }
999       LSldap :: connect(self :: $ldapServer['ldap_config']);
1000       if (LSldap :: isConnected()) {
1001         return true;
1002       }
1003       else {
1004         return;
1005       }
1006     }
1007     else {
1008       LSerror :: addErrorCode('LSsession_03');
1009       return;
1010     }
1011   }
1012
1013   /**
1014    * Use this function to know if subDn is enabled for the curent LdapServer
1015    * 
1016    * @retval boolean
1017    **/
1018   public static function subDnIsEnabled() {
1019     if (!isset(self :: $ldapServer['subDn'])) {
1020       return;
1021     }
1022     if ( !is_array(self :: $ldapServer['subDn']) ) {
1023       return;
1024     }
1025     return true;
1026   }
1027
1028  /**
1029   * Retourne les sous-dns du serveur Ldap courant
1030   *
1031   * @retval mixed Tableau des subDn, false si une erreur est survenue.
1032   */
1033   public static function getSubDnLdapServer() {
1034     if (self :: cacheSudDn() && isset(self :: $_subDnLdapServer[self :: $ldapServerId])) {
1035       return self :: $_subDnLdapServer[self :: $ldapServerId];
1036     }
1037     if (!self::subDnIsEnabled()) {
1038       return;
1039     }
1040     $return=array();
1041     foreach(self :: $ldapServer['subDn'] as $subDn_name => $subDn_config) {
1042       if ($subDn_name == 'LSobject') {
1043         if (is_array($subDn_config)) {
1044           foreach($subDn_config as $LSobject_name => $LSoject_config) {
1045             if ($LSoject_config['basedn']) {
1046               $basedn = $LSoject_config['basedn'];
1047             }
1048             else {
1049               $basedn = self::getRootDn();
1050             }
1051             if ($LSoject_config['displayName']) {
1052               $displayName = $LSoject_config['displayName'];
1053             }
1054             else {
1055               $displayName = NULL;
1056             }
1057             if( self :: loadLSobject($LSobject_name) ) {
1058               if ($subdnobject = new $LSobject_name()) {
1059                 $tbl_return = $subdnobject -> getSelectArray(NULL,$basedn,$displayName);
1060                 if (is_array($tbl_return)) {
1061                   $return=array_merge($return,$tbl_return);
1062                 }
1063                 else {
1064                   LSerror :: addErrorCode('LSsession_17',3);
1065                 }
1066               }
1067               else {
1068                 LSerror :: addErrorCode('LSsession_17',2);
1069               }
1070             }
1071           }
1072         }
1073         else {
1074           LSerror :: addErrorCode('LSsession_17',1);
1075         }
1076       }
1077       else {
1078         if ((isCompatibleDNs($subDn_config['dn'],self :: $ldapServer['ldap_config']['basedn']))&&($subDn_config['dn']!="")) {
1079           $return[$subDn_config['dn']] = __($subDn_name);
1080         }
1081       }
1082     }
1083     if (self :: cacheSudDn()) {
1084       self :: $_subDnLdapServer[self :: $ldapServerId]=$return;
1085       $_SESSION['LSsession_subDnLdapServer'] = self :: $_subDnLdapServer;
1086     }
1087     return $return;
1088   }
1089   
1090   /**
1091    * Retourne la liste de subDn du serveur Ldap utilise
1092    * trié par la profondeur dans l'arboressence (ordre décroissant)
1093    * 
1094    * @return array() Tableau des subDn trié
1095    */  
1096   public static function getSortSubDnLdapServer() {
1097     $subDnLdapServer = self :: getSubDnLdapServer();
1098     if (!$subDnLdapServer) {
1099       return array();
1100     }
1101     uksort($subDnLdapServer,"compareDn");
1102     return $subDnLdapServer;
1103   }
1104
1105  /**
1106   * Retourne les options d'une liste déroulante pour le choix du topDn
1107   * de connexion au serveur Ldap
1108   *
1109   * Liste les subdn (self :: $ldapServer['subDn'])
1110   *
1111   * @retval string Les options (<option>) pour la sélection du topDn.
1112   */
1113   public static function getSubDnLdapServerOptions($selected=NULL) {
1114     $list = self :: getSubDnLdapServer();
1115     if ($list) {
1116       asort($list);
1117       $display='';
1118       foreach($list as $dn => $txt) {
1119         if ($selected && ($selected==$dn)) {
1120           $selected_txt = ' selected';
1121         }
1122         else {
1123           $selected_txt = '';
1124         }
1125         $display.="<option value=\"".$dn."\"$selected_txt>".$txt."</option>\n"; 
1126       }
1127       return $display;
1128     }
1129     return;
1130   }
1131
1132  /**
1133   * Vérifie qu'un subDn est déclaré
1134   *
1135   * @param[in] string Un subDn
1136   * 
1137   * @retval boolean True si le subDn existe, False sinon
1138   */
1139   public static function validSubDnLdapServer($subDn) {
1140     $listTopDn = self :: getSubDnLdapServer();
1141     if(is_array($listTopDn)) {
1142       foreach($listTopDn as $dn => $txt) {
1143         if ($subDn==$dn) {
1144           return true;
1145         } // end if
1146       } // end foreach
1147     } // end if
1148     return;
1149   }
1150
1151  /**
1152   * Test un couple LSobject/pwd
1153   *
1154   * Test un bind sur le serveur avec le dn de l'objet et le mot de passe fourni.
1155   *
1156   * @param[in] LSobject L'object "user" pour l'authentification
1157   * @param[in] string Le mot de passe Ã  tester
1158   *
1159   * @retval boolean True si l'authentification Ã  réussi, false sinon.
1160   */
1161   public static function checkUserPwd($object,$pwd) {
1162     return LSldap :: checkBind($object -> getValue('dn'),$pwd);
1163   }
1164
1165  /**
1166   * Affiche le formulaire de login
1167   *
1168   * Défini les informations pour le template Smarty du formulaire de login.
1169   *
1170   * @retval void
1171   */
1172   public static function displayLoginForm() {
1173     $GLOBALS['Smarty'] -> assign('pagetitle',_('Connection'));
1174     if (isset($_GET['LSsession_logout'])) {
1175       $GLOBALS['Smarty'] -> assign('loginform_action','index.php');
1176     }
1177     else {
1178       $GLOBALS['Smarty'] -> assign('loginform_action',$_SERVER['REQUEST_URI']);
1179     }
1180     if (count(LSconfig :: get('ldap_servers'))==1) {
1181       $GLOBALS['Smarty'] -> assign('loginform_ldapserver_style','style="display: none"');
1182     }
1183     $GLOBALS['Smarty'] -> assign('loginform_label_ldapserver',_('LDAP server'));
1184     $ldapservers_name=array();
1185     $ldapservers_index=array();
1186     foreach(LSconfig :: get('ldap_servers') as $id => $infos) {
1187       $ldapservers_index[]=$id;
1188       $ldapservers_name[]=__($infos['name']);
1189     }
1190     $GLOBALS['Smarty'] -> assign('loginform_ldapservers_name',$ldapservers_name);
1191     $GLOBALS['Smarty'] -> assign('loginform_ldapservers_index',$ldapservers_index);
1192
1193     $GLOBALS['Smarty'] -> assign('loginform_label_level',_('Level'));
1194     $GLOBALS['Smarty'] -> assign('loginform_label_user',_('Identifier'));
1195     $GLOBALS['Smarty'] -> assign('loginform_label_pwd',_('Password'));
1196     $GLOBALS['Smarty'] -> assign('loginform_label_submit',_('Connect'));
1197     $GLOBALS['Smarty'] -> assign('loginform_label_recoverPassword',_('Forgot your password ?'));
1198     
1199     self :: setTemplate('login.tpl');
1200     self :: addJSscript('LSsession_login.js');
1201   }
1202
1203  /**
1204   * Affiche le formulaire de récupération de mot de passe
1205   *
1206   * Défini les informations pour le template Smarty du formulaire de 
1207   * récupération de mot de passe
1208   * 
1209   * @param[in] $infos array() Information sur le status du processus de 
1210   *                           recouvrement de mot de passe
1211   *
1212   * @retval void
1213   */
1214   public static function displayRecoverPasswordForm($recoveryPasswordInfos) {
1215     $GLOBALS['Smarty'] -> assign('pagetitle',_('Recovery of your credentials'));
1216     $GLOBALS['Smarty'] -> assign('recoverpasswordform_action','index.php?LSsession_recoverPassword');
1217     
1218     if (count(LSconfig :: get('ldap_servers'))==1) {
1219       $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapserver_style','style="display: none"');
1220     }
1221     
1222     $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_ldapserver',_('LDAP server'));
1223     $ldapservers_name=array();
1224     $ldapservers_index=array();
1225     foreach(LSconfig :: get('ldap_servers') as $id => $infos) {
1226       $ldapservers_index[]=$id;
1227       $ldapservers_name[]=$infos['name'];
1228     }
1229     $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapservers_name',$ldapservers_name);
1230     $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapservers_index',$ldapservers_index);
1231
1232     $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_user',_('Identifier'));
1233     $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_submit',_('Validate'));
1234     $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_back',_('Back'));
1235     
1236     $recoverpassword_msg = _('Please fill the identifier field to proceed recovery procedure');
1237     
1238     if (isset($recoveryPasswordInfos['recoveryHashMail'])) {
1239       $recoverpassword_msg = getFData(
1240         _("An email has been sent to  %{mail}. " .
1241         "Please follow the instructions on it."),
1242         $recoveryPasswordInfos['recoveryHashMail']
1243       );
1244     }
1245     
1246     if (isset($recoveryPasswordInfos['newPasswordMail'])) {
1247       $recoverpassword_msg = getFData(
1248         _("Your new password has been sent to %{mail}. "),
1249         $recoveryPasswordInfos['newPasswordMail']
1250       );
1251     }
1252     
1253     $GLOBALS['Smarty'] -> assign('recoverpassword_msg',$recoverpassword_msg);
1254     
1255     self :: setTemplate('recoverpassword.tpl');
1256     self :: addJSscript('LSsession_recoverPassword.js');
1257   }
1258
1259  /**
1260   * Défini le template Smarty Ã  utiliser
1261   *
1262   * Remarque : les fichiers de templates doivent se trouver dans le dossier 
1263   * templates/.
1264   *
1265   * @param[in] string Le nom du fichier de template
1266   *
1267   * @retval void
1268   */
1269   public static function setTemplate($template) {
1270     self :: $template = $template;
1271   }
1272
1273  /**
1274   * Ajoute un script JS au chargement de la page
1275   *
1276   * Remarque : les scripts doivents Ãªtre dans le dossier LS_JS_DIR.
1277   *
1278   * @param[in] $script Le nom du fichier de script Ã  charger.
1279   *
1280   * @retval void
1281   */
1282   public static function addJSscript($file,$path=NULL) {
1283     $script=array(
1284       'file' => $file,
1285       'path' => $path
1286     );
1287     self :: $JSscripts[$path.$file]=$script;
1288   }
1289
1290  /**
1291   * Ajouter un paramètre de configuration Javascript
1292   * 
1293   * @param[in] $name string Nom de la variable de configuration
1294   * @param[in] $val mixed Valeur de la variable de configuration
1295   *
1296   * @retval void
1297   */
1298   public static function addJSconfigParam($name,$val) {
1299     self :: $_JSconfigParams[$name]=$val;
1300   }
1301
1302  /**
1303   * Ajoute une feuille de style au chargement de la page
1304   *
1305   * Remarque : les scripts doivents Ãªtre dans le dossier LS_CSS_DIR.
1306   *
1307   * @param[in] $script Le nom du fichier css Ã  charger.
1308   *
1309   * @retval void
1310   */
1311   public static function addCssFile($file,$path=NULL) {
1312     $cssFile=array(
1313       'file' => $file,
1314       'path' => $path
1315     );
1316     self :: $CssFiles[$path.$file]=$cssFile;
1317   }
1318
1319  /**
1320   * Affiche le template Smarty
1321   *
1322   * Charge les dépendances et affiche le template Smarty
1323   *
1324   * @retval void
1325   */
1326   public static function displayTemplate() {
1327     // JS
1328     $JSscript_txt='';
1329     foreach ($GLOBALS['defaultJSscipts'] as $script) {
1330       $JSscript_txt.="<script src='".LS_JS_DIR.$script."' type='text/javascript'></script>\n";
1331     }
1332
1333     foreach (self :: $JSscripts as $script) {
1334       if (!$script['path']) {
1335         $script['path']=LS_JS_DIR;
1336       }
1337       else {
1338         $script['path'].='/';
1339       }
1340       $JSscript_txt.="<script src='".$script['path'].$script['file']."' type='text/javascript'></script>\n";
1341     }
1342
1343     $KAconf = LSconfig :: get('keepLSsessionActive');
1344     if ( 
1345           (
1346             (!isset(self :: $ldapServer['keepLSsessionActive']))
1347             &&
1348             (!($KAconf === false))
1349           )
1350           ||
1351           (self :: $ldapServer['keepLSsessionActive'])
1352         ) {
1353       self :: addJSconfigParam('keepLSsessionActive',ini_get('session.gc_maxlifetime'));
1354     }
1355
1356     $GLOBALS['Smarty'] -> assign('LSjsConfig',json_encode(self :: $_JSconfigParams));
1357     
1358     if (LSdebug) {
1359       $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 1;</script>\n";
1360     }
1361     else {
1362       $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 0;</script>\n";
1363     }
1364     
1365     $GLOBALS['Smarty'] -> assign('LSsession_js',$JSscript_txt);
1366
1367     // Css
1368     self :: addCssFile("LSdefault.css");
1369     $Css_txt='';
1370     foreach (self :: $CssFiles as $file) {
1371       if (!$file['path']) {
1372         $file['path']=LS_CSS_DIR.'/';
1373       }
1374       $Css_txt.="<link rel='stylesheet' type='text/css' href='".$file['path'].$file['file']."' />\n";
1375     }
1376     $GLOBALS['Smarty'] -> assign('LSsession_css',$Css_txt);
1377   
1378     if (isset(self :: $LSaccess[self :: $topDn])) {
1379       $GLOBALS['Smarty'] -> assign('LSaccess',self :: $LSaccess[self :: $topDn]);
1380     }
1381     
1382     // Niveau
1383     $listTopDn = self :: getSubDnLdapServer();
1384     if (is_array($listTopDn)) {
1385       asort($listTopDn);
1386       $GLOBALS['Smarty'] -> assign('label_level',self :: getSubDnLabel());
1387       $GLOBALS['Smarty'] -> assign('_refresh',_('Refresh'));
1388       $LSsession_topDn_index = array();
1389       $LSsession_topDn_name = array();
1390       foreach($listTopDn as $index => $name) {
1391         $LSsession_topDn_index[]  = $index;
1392         $LSsession_topDn_name[]   = $name;
1393       }
1394       $GLOBALS['Smarty'] -> assign('LSsession_subDn_indexes',$LSsession_topDn_index);
1395       $GLOBALS['Smarty'] -> assign('LSsession_subDn_names',$LSsession_topDn_name);
1396       $GLOBALS['Smarty'] -> assign('LSsession_subDn',self :: $topDn);
1397       $GLOBALS['Smarty'] -> assign('LSsession_subDnName',self :: getSubDnName());
1398     }
1399     
1400     $GLOBALS['Smarty'] -> assign('LSlanguages',self :: getLangList());
1401     $GLOBALS['Smarty'] -> assign('LSlang',self :: $lang);
1402     $GLOBALS['Smarty'] -> assign('LSencoding',self :: $encoding);
1403     $GLOBALS['Smarty'] -> assign('lang_label',_('Language'));
1404     
1405     $GLOBALS['Smarty'] -> assign('displayLogoutBtn',self :: $authParams['displayLogoutBtn']);
1406
1407     // Infos
1408     if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
1409       $txt_infos="<ul>\n";
1410       foreach($_SESSION['LSsession_infos'] as $info) {
1411         $txt_infos.="<li>$info</li>\n";
1412       }
1413       $txt_infos.="</ul>\n";
1414       $GLOBALS['Smarty'] -> assign('LSinfos',$txt_infos);
1415       $_SESSION['LSsession_infos']=array();
1416     }
1417     
1418     if (self :: $ajaxDisplay) {
1419       $GLOBALS['Smarty'] -> assign('LSerror_txt',LSerror :: getErrors());
1420       $GLOBALS['Smarty'] -> assign('LSdebug_txt',LSdebug_print(true));
1421     }
1422     else {
1423       LSerror :: display();
1424       LSdebug_print();
1425     }
1426     if (!self :: $template)
1427       self :: setTemplate('empty.tpl');
1428       
1429     $GLOBALS['Smarty'] -> assign('connected_as',_("Connected as"));
1430     
1431     $GLOBALS['Smarty'] -> display(self :: $template);
1432   }
1433   
1434  /**
1435   * Défini que l'affichage se fera ou non via un retour Ajax
1436   * 
1437   * @param[in] $val boolean True pour que l'affichage se fasse par un retour
1438   *                         Ajax, false sinon
1439   * @retval void
1440   */
1441   public static function setAjaxDisplay($val=true) {
1442     self :: $ajaxDisplay = (boolean)$val;
1443   }
1444   
1445  /**
1446   * Affiche un retour Ajax
1447   *
1448   * @retval void
1449   */
1450   public static function displayAjaxReturn($data=array()) {
1451     if (isset($data['LSredirect']) && (!LSdebugDefined()) ) {
1452       echo json_encode($data);
1453       return;
1454     }
1455     
1456     $data['LSjsConfig'] = self :: $_JSconfigParams;
1457     
1458     // Infos
1459     if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
1460       $txt_infos="<ul>\n";
1461       foreach($_SESSION['LSsession_infos'] as $info) {
1462         $txt_infos.="<li>$info</li>\n";
1463       }
1464       $txt_infos.="</ul>\n";
1465       $data['LSinfos'] = $txt_infos;
1466       $_SESSION['LSsession_infos']=array();
1467     }
1468     
1469     if (LSerror :: errorsDefined()) {
1470       $data['LSerror'] = LSerror :: getErrors();
1471     }
1472
1473     if (isset($_REQUEST['imgload'])) {
1474       $data['imgload'] = $_REQUEST['imgload'];
1475     }
1476
1477     if (LSdebugDefined()) {
1478       $data['LSdebug'] = LSdebug_print(true,false);
1479     }
1480
1481     echo json_encode($data);  
1482   }
1483  
1484  /**
1485   * Retournne un template Smarty compilé
1486   *
1487   * @param[in] string $template Le template à retourner
1488   * @param[in] array $variables Variables Smarty à assigner avant l'affichage
1489   * 
1490   * @retval string Le HTML compilé du template
1491   */
1492   public static function fetchTemplate($template,$variables=array()) {
1493     foreach($variables as $name => $val) {
1494       $GLOBALS['Smarty'] -> assign($name,$val);
1495     }
1496     return $GLOBALS['Smarty'] -> fetch($template);
1497   }
1498   
1499   /**
1500    * Charge les droits LS de l'utilisateur
1501    * 
1502    * @retval boolean True si le chargement Ã  réussi, false sinon.
1503    **/
1504   private static function loadLSprofiles() {
1505     if (is_array(self :: $ldapServer['LSprofiles'])) {
1506       foreach (self :: $ldapServer['LSprofiles'] as $profile => $profileInfos) {
1507         if (is_array($profileInfos)) {
1508           foreach ($profileInfos as $topDn => $rightsInfos) {
1509             /*
1510              * If $topDn == 'LSobject', we search for each LSobject type to find
1511              * all items on witch the user will have powers.
1512              */
1513             if ($topDn == 'LSobjects') {
1514               if (is_array($rightsInfos)) {
1515                 foreach ($rightsInfos as $LSobject => $listInfos) {
1516                   if (self :: loadLSclass('LSsearch')) {
1517                     if ($listInfos['filter']) {
1518                       $filter = self :: getLSuserObject() -> getFData($listInfos['filter']);
1519                     }
1520                     else {
1521                       $filter = '('.$listInfos['attr'].'='.self :: getLSuserObject() -> getFData($listInfos['attr_value']).')';
1522                     }
1523                     
1524                     $params = array (
1525                       'basedn' => $listInfos['basedn'],
1526                       'filter' => $filter
1527                     );
1528                     
1529                     if (is_array($listInfos['params'])) {
1530                       $params = array_merge($listInfos['params'],$params);
1531                     }
1532                     
1533                     $LSsearch = new LSsearch($LSobject,'LSsession :: loadLSprofiles',$params,true);
1534                     $LSsearch -> run(false);
1535                     
1536                     $LSprofiles[$profile] = $LSsearch -> listObjectsDn();
1537                   }
1538                 }
1539               }
1540               else {
1541                 LSdebug('LSobjects => [] doit etre un tableau');
1542               }
1543             }
1544             else {
1545               if (is_array($rightsInfos)) {
1546                 foreach($rightsInfos as $dn => $conf) {
1547                   if ((isset($conf['attr'])) && (isset($conf['LSobject']))) {
1548                     if( self :: loadLSobject($conf['LSobject']) ) {
1549                       if ($object = new $conf['LSobject']()) {
1550                         if ($object -> loadData($dn)) {
1551                           $listDns=$object -> getValue($conf['attr']);
1552                           $valKey = (isset($conf['attr_value']))?$conf['attr_value']:'%{dn}';
1553                           $val = self :: getLSuserObject() -> getFData($valKey);
1554                           if (is_array($listDns)) {
1555                             if (in_array($val,$listDns)) {
1556                               self :: $LSprofiles[$profile][] = $topDn;
1557                             }
1558                           }
1559                         }
1560                         else {
1561                           LSdebug('Impossible de chargé le dn : '.$dn);
1562                         }
1563                       }
1564                       else {
1565                         LSdebug('Impossible de créer l\'objet de type : '.$conf['LSobject']);
1566                       }
1567                     }
1568                   }
1569                   else {
1570                     if (self :: $dn == $dn) {
1571                       self :: $LSprofiles[$profile][] = $topDn;
1572                     }
1573                   }
1574                 }
1575               }
1576               else {
1577                 if ( self :: $dn == $rightsInfos ) {
1578                   self :: $LSprofiles[$profile][] = $topDn;
1579                 }
1580               }
1581             } // fin else ($topDn == 'LSobjects')
1582           } // fin foreach($profileInfos)
1583         } // fin is_array($profileInfos)
1584       } // fin foreach LSprofiles
1585       LSdebug(self :: $LSprofiles);
1586       return true;
1587     }
1588     else {
1589       return;
1590     }
1591   }
1592   
1593   /**
1594    * Charge les droits d'accès de l'utilisateur pour construire le menu de l'interface
1595    *
1596    * @retval void
1597    */
1598   private static function loadLSaccess() {
1599     $LSaccess=array();
1600     if (is_array(self :: $ldapServer['subDn'])) {
1601       foreach(self :: $ldapServer['subDn'] as $name => $config) {
1602         if ($name=='LSobject') {
1603           if (is_array($config)) {
1604
1605             // Définition des subDns 
1606             foreach($config as $objectType => $objectConf) {
1607               if (self :: loadLSobject($objectType)) {
1608                 if ($subdnobject = new $objectType()) {
1609                   $tbl = $subdnobject -> getSelectArray(NULL,self::getRootDn(),NULL,NULL,false);
1610                   if (is_array($tbl)) {
1611                     // Définition des accès
1612                     $access=array();
1613                     if (is_array($objectConf['LSobjects'])) {
1614                       foreach($objectConf['LSobjects'] as $type) {
1615                         if (self :: loadLSobject($type)) {
1616                           if (self :: canAccess($type)) {
1617                             $access[$type] = LSconfig :: get('LSobjects.'.$type.'.label');
1618                           }
1619                         }
1620                       }
1621                     }
1622                     foreach($tbl as $dn => $dn_name) {
1623                       $LSaccess[$dn]=$access;
1624                     }
1625                   }
1626                 }
1627               }
1628             }
1629           }
1630         }
1631         else {
1632           if ((isCompatibleDNs(self :: $ldapServer['ldap_config']['basedn'],$config['dn']))&&($config['dn']!='')) {
1633             $access=array();
1634             if (is_array($config['LSobjects'])) {
1635               foreach($config['LSobjects'] as $objectType) {
1636                 if (self :: loadLSobject($objectType)) {
1637                   if (self :: canAccess($objectType)) {
1638                     $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label');
1639                   }
1640                 }
1641               }
1642             }
1643             $LSaccess[$config['dn']]=$access;
1644           }
1645         }
1646       }
1647     }
1648     else {
1649       if(is_array(self :: $ldapServer['LSaccess'])) {
1650         $access=array();
1651         foreach(self :: $ldapServer['LSaccess'] as $objectType) {
1652           if (self :: loadLSobject($objectType)) {
1653             if (self :: canAccess($objectType)) {
1654                 $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label');
1655             }
1656           }
1657         }
1658         $LSaccess[self :: $topDn] = $access;
1659       }
1660     }
1661     foreach($LSaccess as $dn => $access) {
1662       $LSaccess[$dn] = array_merge(
1663         array(
1664           'SELF' => 'My account'
1665         ),
1666         $access
1667       );
1668     }
1669     
1670     self :: $LSaccess = $LSaccess;
1671     $_SESSION['LSsession']['LSaccess'] = $LSaccess;
1672   }
1673   
1674   /**
1675    * Dit si l'utilisateur est du profil pour le DN spécifié
1676    *
1677    * @param[in] string $profile de l'objet
1678    * @param[in] string $dn DN de l'objet
1679    * 
1680    * @retval boolean True si l'utilisateur est du profil sur l'objet, false sinon.
1681    */
1682   public static function isLSprofile($dn,$profile) {
1683     if (is_array(self :: $LSprofiles[$profile])) {
1684       foreach(self :: $LSprofiles[$profile] as $topDn) {
1685         if($dn == $topDn) {
1686           return true;
1687         }
1688         else if ( isCompatibleDNs($dn,$topDn) ) {
1689           return true;
1690         }
1691       }
1692     }
1693     return;
1694   }
1695   
1696   /**
1697    * Retourne qui est l'utilisateur par rapport Ã  l'object
1698    *
1699    * @param[in] string Le DN de l'objet
1700    * 
1701    * @retval string 'admin'/'self'/'user' pour Admin , l'utilisateur lui même ou un simple utilisateur
1702    */
1703   public static function whoami($dn) {
1704     $retval = array('user');
1705     
1706     foreach(self :: $LSprofiles as $profile => $infos) {
1707       if(self :: isLSprofile($dn,$profile)) {
1708        $retval[]=$profile;
1709       }
1710     }
1711     
1712     if (self :: $dn == $dn) {
1713       $retval[]='self';
1714     }
1715     
1716     return $retval;
1717   }
1718   
1719   /**
1720    * Retourne le droit de l'utilisateur Ã  accèder Ã  un objet
1721    * 
1722    * @param[in] string $LSobject Le type de l'objet
1723    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1724    * @param[in] string $right Le type de droit d'accès Ã  tester ('r'/'w')
1725    * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1726    *
1727    * @retval boolean True si l'utilisateur a accès, false sinon
1728    */
1729   public static function canAccess($LSobject,$dn=NULL,$right=NULL,$attr=NULL) {
1730     if (!self :: loadLSobject($LSobject)) {
1731       return;
1732     }
1733     if ($dn) {
1734       $whoami = self :: whoami($dn);
1735       if ($dn==self :: getLSuserObject() -> getValue('dn')) {
1736         if (!self :: in_menu('SELF')) {
1737           return;
1738         }
1739       }
1740       else {
1741         $obj = new $LSobject();
1742         $obj -> dn = $dn;
1743         if (!self :: in_menu($LSobject,$obj -> subDnValue)) {
1744           return;
1745         }
1746       }
1747     }
1748     else {
1749       $objectdn=LSconfig :: get('LSobjects.'.$LSobject.'.container_dn').','.self :: $topDn;
1750       $whoami = self :: whoami($objectdn);
1751     }
1752     
1753     // Pour un attribut particulier
1754     if ($attr) {
1755       if ($attr=='rdn') {
1756         $attr=LSconfig :: get('LSobjects.'.$LSobject.'.rdn');
1757       }
1758       if (!is_array(LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr))) {
1759         return;
1760       }
1761
1762       $r = 'n';
1763       foreach($whoami as $who) {
1764         $nr = LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr.'.rights.'.$who);
1765         if($nr == 'w') {
1766           $r = 'w';
1767         }
1768         else if($nr == 'r') {
1769           if ($r=='n') {
1770             $r='r';
1771           }
1772         }
1773       }
1774       
1775       if (($right=='r')||($right=='w')) {
1776         if ($r==$right) {
1777           return true;
1778         }
1779         return;
1780       }
1781       else {
1782         if ( ($r=='r') || ($r=='w') ) {
1783           return true;
1784         }
1785         return;
1786       }
1787     }
1788     
1789     // Pour un attribut quelconque
1790     $attrs_conf=LSconfig :: get('LSobjects.'.$LSobject.'.attrs');
1791     if (is_array($attrs_conf)) {
1792       if (($right=='r')||($right=='w')) {
1793         foreach($whoami as $who) {
1794           foreach ($attrs_conf as $attr_name => $attr_config) {
1795             if ($attr_config['rights'][$who]==$right) {
1796               return true;
1797             }
1798           }
1799         }
1800       }
1801       else {
1802         foreach($whoami as $who) {
1803           foreach ($attrs_conf as $attr_name => $attr_config) {
1804             if ( ($attr_config['rights'][$who]=='r') || ($attr_config['rights'][$who]=='w') ) {
1805               return true;
1806             }
1807           }
1808         }
1809       }
1810     }
1811     return;
1812   }
1813   
1814   /**
1815    * Retourne le droit de l'utilisateur Ã  editer Ã  un objet
1816    * 
1817    * @param[in] string $LSobject Le type de l'objet
1818    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1819    * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1820    *
1821    * @retval boolean True si l'utilisateur a accès, false sinon
1822    */
1823   public static function canEdit($LSobject,$dn=NULL,$attr=NULL) {
1824     return self :: canAccess($LSobject,$dn,'w',$attr);
1825   }
1826
1827   /**
1828    * Retourne le droit de l'utilisateur Ã  supprimer un objet
1829    * 
1830    * @param[in] string $LSobject Le type de l'objet
1831    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1832    *
1833    * @retval boolean True si l'utilisateur a accès, false sinon
1834    */  
1835   public static function canRemove($LSobject,$dn) {
1836     return self :: canAccess($LSobject,$dn,'w','rdn');
1837   }
1838   
1839   /**
1840    * Retourne le droit de l'utilisateur Ã  créer un objet
1841    * 
1842    * @param[in] string $LSobject Le type de l'objet
1843    *
1844    * @retval boolean True si l'utilisateur a accès, false sinon
1845    */    
1846   public static function canCreate($LSobject) {
1847     if (!self :: loadLSobject($LSobject)) {
1848       return;
1849     }
1850     if (LSconfig :: get("LSobjects.$LSobject.disable_creation")) {
1851       return;
1852     }
1853     return self :: canAccess($LSobject,NULL,'w','rdn');
1854   }
1855   
1856   /**
1857    * Retourne le droit de l'utilisateur Ã  gérer la relation d'objet
1858    * 
1859    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1860    * @param[in] string $LSobject Le type de l'objet
1861    * @param[in] string $relationName Le nom de la relation avec l'objet
1862    * @param[in] string $right Le type de droit a vérifier ('r' ou 'w')
1863    *
1864    * @retval boolean True si l'utilisateur a accès, false sinon
1865    */
1866   public static function relationCanAccess($dn,$LSobject,$relationName,$right=NULL) {
1867     $relConf=LSconfig :: get('LSobjects.'.$LSobject.'.LSrelation.'.$relationName);
1868     if (!is_array($relConf))
1869       return;
1870     $whoami = self :: whoami($dn);
1871
1872     if (($right=='w') || ($right=='r')) {
1873       $r = 'n';
1874       foreach($whoami as $who) {
1875         $nr = $relConf['rights'][$who];
1876         if($nr == 'w') {
1877           $r = 'w';
1878         }
1879         else if($nr == 'r') {
1880           if ($r=='n') {
1881             $r='r';
1882           }
1883         }
1884       }
1885       
1886       if ($r == $right) {
1887         return true;
1888       }
1889     }
1890     else {
1891       foreach($whoami as $who) {
1892         if (($relConf['rights'][$who] == 'w') || ($relConf['rights'][$who] == 'r')) {
1893           return true;
1894         }
1895       }
1896     }
1897     return;
1898   }
1899
1900   /**
1901    * Retourne le droit de l'utilisateur Ã  modifier la relation d'objet
1902    * 
1903    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1904    * @param[in] string $LSobject Le type de l'objet
1905    * @param[in] string $relationName Le nom de la relation avec l'objet
1906    *
1907    * @retval boolean True si l'utilisateur a accès, false sinon
1908    */  
1909   public static function relationCanEdit($dn,$LSobject,$relationName) {
1910     return self :: relationCanAccess($dn,$LSobject,$relationName,'w');
1911   }
1912
1913   /**
1914    * Ajoute un fichier temporaire
1915    * 
1916    * @author Benjamin Renard <brenard@easter-eggs.com>
1917    * 
1918    * @retval void
1919    **/
1920   public static function addTmpFile($value,$filePath) {
1921     $hash = mhash(MHASH_MD5,$value);
1922     self :: $tmp_file[$filePath] = $hash;
1923     $_SESSION['LSsession']['tmp_file'][$filePath] = $hash;
1924   }
1925   
1926   /**
1927    * Retourne le chemin du fichier temporaire si l'existe
1928    * 
1929    * @author Benjamin Renard <brenard@easter-eggs.com>
1930    * 
1931    * @param[in] $value La valeur du fichier
1932    * 
1933    * @retval mixed 
1934    **/
1935   public static function tmpFileExist($value) {
1936     $hash = mhash(MHASH_MD5,$value);
1937     foreach(self :: $tmp_file as $filePath => $contentHash) {
1938       if ($hash == $contentHash) {
1939         return $filePath;
1940       }
1941     }
1942     return false;
1943   }
1944   
1945   /**
1946    * Retourne le chemin du fichier temporaire
1947    * 
1948    * Retourne le chemin du fichier temporaire qu'il créera Ã  partir de la valeur
1949    * s'il n'existe pas déjà.
1950    * 
1951    * @author Benjamin Renard <brenard@easter-eggs.com>
1952    * 
1953    * @param[in] $value La valeur du fichier
1954    * 
1955    * @retval mixed 
1956    **/
1957   public static function getTmpFile($value) {
1958     $exist = self :: tmpFileExist($value);
1959     if (!$exist) {
1960       $img_path = LS_TMP_DIR .rand().'.tmp';
1961       $fp = fopen($img_path, "w");
1962       fwrite($fp, $value);
1963       fclose($fp);
1964       self :: addTmpFile($value,$img_path);
1965       return $img_path;
1966     }
1967     else {
1968       return $exist;
1969     }
1970   }
1971   
1972   /**
1973    * Supprime les fichiers temporaires
1974    * 
1975    * @author Benjamin Renard <brenard@easter-eggs.com>
1976    * 
1977    * @retval void
1978    **/
1979   public static function deleteTmpFile($filePath=NULL) {
1980     if ($filePath) {
1981         @unlink($filePath);
1982         unset(self :: $tmp_file[$filePath]);
1983         unset($_SESSION['LSsession']['tmp_file'][$filePath]);
1984     }
1985     else {
1986       foreach(self :: $tmp_file as $file => $content) {
1987         @unlink($file);
1988       }
1989       self :: $tmp_file = array();
1990       $_SESSION['LSsession']['tmp_file'] = array();
1991     }
1992   }
1993
1994   /**
1995    * Retourne true si le cache des droits est activé
1996    *
1997    * @author Benjamin Renard <brenard@easter-eggs.com>
1998    * 
1999    * @retval boolean True si le cache des droits est activé, false sinon.
2000    */
2001   public static function cacheLSprofiles() {
2002     return ( (LSconfig :: get('cacheLSprofiles')) || (self :: $ldapServer['cacheLSprofiles']) );
2003   }
2004
2005   /**
2006    * Retourne true si le cache des subDn est activé
2007    *
2008    * @author Benjamin Renard <brenard@easter-eggs.com>
2009    * 
2010    * @retval boolean True si le cache des subDn est activé, false sinon.
2011    */
2012   public static function cacheSudDn() {
2013     return ( (LSconfig :: get('cacheSubDn')) || (self :: $ldapServer['cacheSubDn']));
2014   }
2015   
2016   /**
2017    * Retourne true si le cache des recherches est activé
2018    *
2019    * @author Benjamin Renard <brenard@easter-eggs.com>
2020    * 
2021    * @retval boolean True si le cache des recherches est activé, false sinon.
2022    */
2023   public static function cacheSearch() {
2024     return ( (LSconfig :: get('cacheSearch')) || (self :: $ldapServer['cacheSearch']));
2025   }
2026   
2027   /**
2028    * Retourne le label des niveaux pour le serveur ldap courant
2029    * 
2030    * @author Benjamin Renard <brenard@easter-eggs.com>
2031    * 
2032    * @retval string Le label des niveaux pour le serveur ldap dourant
2033    */
2034   public static function getSubDnLabel() {
2035     return (self :: $ldapServer['subDnLabel']!='')?__(self :: $ldapServer['subDnLabel']):_('Level');
2036   }
2037   
2038   /**
2039    * Retourne le nom du subDn
2040    * 
2041    * @param[in] $subDn string subDn
2042    * 
2043    * @retval string Le nom du subDn ou '' sinon
2044    */
2045   public static function getSubDnName($subDn=false) {
2046     if (!$subDn) {
2047       $subDn = self :: $topDn;
2048     }
2049     if (self :: getSubDnLdapServer()) {
2050       if (isset(self :: $_subDnLdapServer[self :: $ldapServerId][$subDn])) {
2051         return self :: $_subDnLdapServer[self :: $ldapServerId][$subDn];
2052       }
2053     }
2054     return '';
2055   }
2056
2057   /**
2058    * L'objet est t-il utilisé pour listé les subDnS
2059    * 
2060    * @param[in] $type string Le type d'objet
2061    * 
2062    * @retval boolean true si le type d'objet est un subDnObject, false sinon
2063    */
2064   public static function isSubDnLSobject($type) {
2065     $result = false;
2066     if (is_array(self :: $ldapServer['subDn']['LSobject'])) {
2067       foreach(self :: $ldapServer['subDn']['LSobject'] as $key => $value) {
2068         if ($key==$type) {
2069           $result=true;
2070         }
2071       }
2072     }
2073     return $result;
2074   }
2075   
2076   /**
2077    * Indique si un type d'objet est dans le menu courant
2078    * 
2079    * @retval boolean true si le type d'objet est dans le menu, false sinon
2080    */
2081   public static function in_menu($LSobject,$topDn=NULL) {
2082     if (!$topDn) {
2083       $topDn=self :: $topDn;
2084     }
2085     return isset(self :: $LSaccess[$topDn][$LSobject]);
2086   }
2087   
2088   /**
2089    * Indique si le serveur LDAP courant a des subDn
2090    * 
2091    * @retval boolean true si le serveur LDAP courant a des subDn, false sinon
2092    */
2093   public static function haveSubDn() {
2094     return (is_array(self :: $ldapServer['subDn']));
2095   }
2096
2097   /**
2098    * Ajoute une information à afficher
2099    * 
2100    * @param[in] $msg string Le message à afficher
2101    * 
2102    * @retval void
2103    */
2104   public static function addInfo($msg) {
2105     $_SESSION['LSsession_infos'][]=$msg;
2106   }
2107   
2108   /**
2109    * Redirection de l'utilisateur vers une autre URL
2110    * 
2111    * @param[in] $url string L'URL
2112    * @param[in] $exit boolean Si true, l'execution script s'arrête après la redirection
2113    * 
2114    * @retval void
2115    */  
2116   public static function redirect($url,$exit=true) {
2117     $GLOBALS['Smarty'] -> assign('url',$url);
2118     $GLOBALS['Smarty'] -> display('redirect.tpl');
2119     if ($exit) {
2120       exit();
2121     }
2122   }
2123   
2124   /**
2125    * Retourne l'adresse mail d'emission configurée pour le serveur courant
2126    * 
2127    * @retval string Adresse mail d'emission
2128    */
2129   public static function getEmailSender() {
2130     return self :: $ldapServer['emailSender'];  
2131   }
2132   
2133   /**
2134    * Ajout d'une information d'aide
2135    * 
2136    * @param[in] $group string Le nom du groupe d'infos dans lequels ajouter
2137    *                          celle-ci
2138    * @param[in] $infos array  Tableau array(name => value) des infos
2139    * 
2140    * @retval void
2141    */
2142   public static function addHelpInfos($group,$infos) {
2143     if (is_array($infos)) {
2144       if (is_array(self :: $_JSconfigParams['helpInfos'][$group])) {
2145         self :: $_JSconfigParams['helpInfos'][$group] = array_merge(self :: $_JSconfigParams['helpInfos'][$group],$infos);
2146       }
2147       else {
2148         self :: $_JSconfigParams['helpInfos'][$group] = $infos;
2149       }
2150     }
2151   }
2152   
2153  /**
2154   * Défini les codes erreur relative à la classe LSsession
2155   * 
2156   * @retval void
2157   */  
2158   private static function defineLSerrors() {
2159     /*
2160      * Error Codes
2161      */
2162     LSerror :: defineError('LSsession_01',
2163     _("LSsession : The constant %{const} is not defined.")
2164     );
2165     LSerror :: defineError('LSsession_02',
2166     _("LSsession : The %{addon} support is uncertain. Verify system compatibility and the add-on configuration.")
2167     );
2168     LSerror :: defineError('LSsession_03',
2169     _("LSsession : LDAP server's configuration data are invalid. Can't connect.")
2170     );
2171     LSerror :: defineError('LSsession_04',
2172     _("LSsession : Failed to load LSobject type %{type} : unknon type.")
2173     );
2174     LSerror :: defineError('LSsession_05',
2175     _("LSsession : Failed to load LSclass %{class}.")
2176     );
2177     LSerror :: defineError('LSsession_06',
2178     _("LSsession : Login or password incorrect.")
2179     );
2180     LSerror :: defineError('LSsession_07',
2181     _("LSsession : Impossible to identify you : Duplication of identities.")
2182     );
2183     LSerror :: defineError('LSsession_08',
2184     _("LSsession : Can't load class of authentification (%{class}).")
2185     );
2186     LSerror :: defineError('LSsession_09',
2187     _("LSsession : Can't connect to LDAP server.")
2188     );
2189     LSerror :: defineError('LSsession_10',
2190     _("LSsession : Impossible to authenticate you.")
2191     );
2192     LSerror :: defineError('LSsession_11',
2193     _("LSsession : Your are not authorized to do this action.")
2194     );
2195     LSerror :: defineError('LSsession_12',
2196     _("LSsession : Some informations are missing to display this page.")
2197     );
2198     // 13 -> 16 : not yet used
2199     LSerror :: defineError('LSsession_17',
2200     _("LSsession : Error during creation of list of levels. Contact administrators. (Code : %{code})")
2201     );
2202     LSerror :: defineError('LSsession_18',
2203     _("LSsession : The password recovery is disabled for this LDAP server.")
2204     );
2205     LSerror :: defineError('LSsession_19',
2206     _("LSsession : Some informations are missing to recover your password. Contact administrators.")
2207     );
2208     LSerror :: defineError('LSsession_20',
2209     _("LSsession : Error during password recovery. Contact administrators.(Step : %{step})")
2210     );
2211     // 21 : not yet used
2212     LSerror :: defineError('LSsession_22',
2213     _("LSsession : problem during initialisation.")
2214     );
2215   }
2216
2217   /**
2218    * Ajax method when change ldapserver on login form
2219    * 
2220    * @param[in] $data array The return data address
2221    * 
2222    * @retval void
2223    **/
2224   public static function ajax_onLdapServerChangedLogin(&$data) {  
2225     if ( isset($_REQUEST['server']) ) {
2226       self :: setLdapServer($_REQUEST['server']);
2227       $data = array();
2228       if ( self :: LSldapConnect() ) {
2229         session_start();
2230         if (isset($_SESSION['LSsession_topDn'])) {
2231           $sel = $_SESSION['LSsession_topDn'];
2232         }
2233         else {
2234           $sel = NULL;
2235         }
2236         $list = self :: getSubDnLdapServerOptions($sel);
2237         if (is_string($list)) {
2238           $data['list_topDn'] = "<select name='LSsession_topDn' id='LSsession_topDn'>".$list."</select>";
2239           $data['subDnLabel'] = self :: getSubDnLabel();
2240         }
2241       }
2242       $data['recoverPassword'] = isset(self :: $ldapServer['recoverPassword']);
2243     }
2244   }
2245   
2246   /**
2247    * Ajax method when change ldapserver on recoverPassword form
2248    * 
2249    * @param[in] $data array The return data address
2250    * 
2251    * @retval void
2252    **/
2253   public static function ajax_onLdapServerChangedRecoverPassword(&$data) {  
2254     if ( isset($_REQUEST['server']) ) {
2255       self :: setLdapServer($_REQUEST['server']);
2256       $data=array('recoverPassword' => isset(self :: $ldapServer['recoverPassword']));
2257     }
2258   }
2259 }
2260
2261 ?>