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