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