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