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