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