- LSsession : Modification de la méthode loadLSaccess() pour prendre en compte
[ldapsaisie.git] / trunk / 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 define('LS_DEFAULT_CONF_DIR','conf');
24
25 /**
26  * Gestion des sessions
27  *
28  * Cette classe gère les sessions d'utilisateurs.
29  *
30  * @author Benjamin Renard <brenard@easter-eggs.com>
31  */
32 class LSsession {
33
34   var $confDir = NULL;
35   var $ldapServer = NULL;
36   var $ldapServerId = NULL;
37   var $topDn = NULL;
38   var $LSuserObject = NULL;
39   var $dn = NULL;
40   var $rdn = NULL;
41   var $JSscripts = array();
42   var $_JSconfigParams = array();
43   var $CssFiles = array();
44   var $template = NULL;
45   var $LSprofiles = array();
46   var $LSaccess = array();
47   var $tmp_file = array();
48   var $_subDnLdapServer = array();
49   var $ajaxDisplay = false;
50
51   /**
52    * Constructeur
53    *
54    * @author Benjamin Renard <brenard@easter-eggs.com>
55    *
56    * @retval void
57    */
58   function LSsession ($configDir=LS_DEFAULT_CONF_DIR) {
59     $this -> confDir = $configDir;
60     if ($this -> loadConfig()) {
61       $this -> startLSerror();
62     }
63     else {
64       return;
65     }
66   }
67
68  /**
69   * Chargement de la configuration
70   *
71   * Chargement des fichiers de configuration et création de l'objet Smarty.
72   *
73   * @author Benjamin Renard <brenard@easter-eggs.com>
74   *
75   * @retval true si tout c'est bien passé, false sinon
76   */
77   function loadConfig() {
78     if (loadDir($this -> confDir, '^config\..*\.php$')) {
79       if ( include_once $GLOBALS['LSconfig']['Smarty'] ) {
80         $GLOBALS['Smarty'] = new Smarty();
81         $GLOBALS['Smarty'] -> template_dir = LS_TEMPLATES_DIR;
82         $GLOBALS['Smarty'] -> compile_dir = LS_TMP_DIR;
83         
84         $GLOBALS['Smarty'] -> assign('LS_CSS_DIR',LS_CSS_DIR);
85         $GLOBALS['Smarty'] -> assign('LS_IMAGES_DIR',LS_IMAGES_DIR);
86         
87         $this -> addJSconfigParam('LS_IMAGES_DIR',LS_IMAGES_DIR);
88         return true;
89       }
90       else {
91         die($GLOBALS['LSerror_code']['LSsession_08']['msg']);
92         return;
93       }
94       return true;
95     }
96     else {
97       return;
98     }
99     
100   }
101
102  /**
103   * Initialisation de la gestion des erreurs
104   *
105   * Création de l'objet LSerror
106   *
107   * @author Benjamin Renard <brenard@easter-eggs.com
108   *
109   * @retval boolean true si l'initialisation a réussi, false sinon.
110   */
111   function startLSerror() {
112     if(!$this -> loadLSclass('LSerror')) {
113       return;
114     }
115     $GLOBALS['LSerror'] = new LSerror();
116     return true;
117   }
118
119  /**
120   * Chargement d'une classe d'LdapSaisie
121   *
122   * @param[in] $class Nom de la classe Ã  charger (Exemple : LSeepeople)
123   * @param[in] $type (Optionnel) Type de classe Ã  charger (Exemple : LSobjects)
124   *
125   * @author Benjamin Renard <brenard@easter-eggs.com
126   * 
127   * @retval boolean true si le chargement a réussi, false sinon.
128   */
129   function loadLSclass($class,$type='') {
130     if (class_exists($class))
131       return true;
132     if($type!='')
133       $type=$type.'.';
134     return @include_once LS_CLASS_DIR .'class.'.$type.$class.'.php';
135   }
136
137  /**
138   * Chargement d'un object LdapSaisie
139   *
140   * @param[in] $object Nom de l'objet Ã  charger
141   *
142   * @retval boolean true si le chargement a réussi, false sinon.
143   */
144   function loadLSobject($object) {
145     $error = 0;
146     $this -> loadLSclass('LSldapObject');
147     if (!$this -> loadLSclass($object,'LSobjects')) {
148       $error = 1;
149     }
150     if (!require_once( LS_OBJECTS_DIR . 'config.LSobjects.'.$object.'.php' )) {
151       $error = 1;
152     }
153     if ($error) {
154       $GLOBALS['LSerror'] -> addErrorCode('LSsession_04',$object);
155       return;
156     }
157     return true;
158   }
159
160  /**
161   * Chargement d'un addons d'LdapSaisie
162   *
163   * @param[in] $addon Nom de l'addon Ã  charger (Exemple : samba)
164   *
165   * @author Benjamin Renard <brenard@easter-eggs.com
166   * 
167   * @retval boolean true si le chargement a réussi, false sinon.
168   */
169   function loadLSaddon($addon) {
170     if(require_once LS_ADDONS_DIR .'LSaddons.'.$addon.'.php') {
171       if (!call_user_func('LSaddon_'. $addon .'_support')) {
172         $GLOBALS['LSerror'] -> addErrorCode('LSsession_02',$addon);
173         return;
174       }
175       return true;
176     }
177     return;
178   }
179
180  /**
181   * Chargement des addons LdapSaisie
182   *
183   * Chargement des LSaddons contenue dans la variable
184   * $GLOBALS['LSaddons']['loads']
185   *
186   * @retval boolean true si le chargement a réussi, false sinon.
187   */
188   function loadLSaddons() {
189     if(!is_array($GLOBALS['LSaddons']['loads'])) {
190       $GLOBALS['LSerror'] -> addErrorCode('LSsession_01',"LSaddons['loads']");
191       return;
192     }
193
194     foreach ($GLOBALS['LSaddons']['loads'] as $addon) {
195       $this -> loadLSaddon($addon);
196     }
197     return true;
198   }
199
200  /**
201   * Initialisation de la session LdapSaisie
202   *
203   * Initialisation d'une LSsession :
204   * - Authentification et activation du mécanisme de session de LdapSaisie
205   * - ou Chargement des paramètres de la session Ã  partir de la variable 
206   *   $_SESSION['LSsession'].
207   * - ou Destruction de la session en cas de $_GET['LSsession_logout'].
208   *
209   * @retval boolean True si l'initialisation Ã  réussi (utilisateur authentifié), false sinon.
210   */
211   function startLSsession() {
212       $this -> loadLSaddons();
213       session_start();
214
215       // Déconnexion
216       if (isset($_GET['LSsession_logout'])||isset($_GET['LSsession_recoverPassword'])) {
217         session_destroy();
218         
219         if (is_array($_SESSION['LSsession']['tmp_file'])) {
220           $this -> tmp_file = $_SESSION['LSsession']['tmp_file'];
221         }
222         $this -> deleteTmpFile();
223         unset($_SESSION['LSsession']);
224       }
225       
226       // Récupération de mot de passe
227       if (isset($_GET['recoveryHash'])) {
228         $_POST['LSsession_user'] = 'a determiner plus tard';
229       }
230       
231       if(isset($_SESSION['LSsession'])) {
232         // Session existante
233         $this -> confDir      = $_SESSION['LSsession']['confDir'];
234         $this -> topDn        = $_SESSION['LSsession']['topDn'];
235         $this -> dn           = $_SESSION['LSsession']['dn'];
236         $this -> rdn          = $_SESSION['LSsession']['rdn'];
237         $this -> ldapServerId = $_SESSION['LSsession']['ldapServerId'];
238         $this -> tmp_file     = $_SESSION['LSsession']['tmp_file'];
239         
240         if ( $this -> cacheLSprofiles() && !isset($_REQUEST['LSsession_refresh']) ) {
241           $this -> ldapServer = $_SESSION['LSsession']['ldapServer'];
242           $this -> LSprofiles   = $_SESSION['LSsession']['LSprofiles'];
243           $this -> LSaccess   = $_SESSION['LSsession']['LSaccess'];
244           if (!$this -> LSldapConnect())
245             return;
246         }
247         else {
248           $this -> setLdapServer($this -> ldapServerId);
249           if (!$this -> LSldapConnect())
250             return;
251           $this -> loadLSprofiles();
252         }
253         
254         if ( $this -> cacheSudDn() && (!isset($_REQUEST['LSsession_refresh'])) ) {
255           $this -> _subDnLdapServer = $_SESSION['LSsession_subDnLdapServer'];
256         }
257         
258         if (!$this -> loadLSobject($this -> ldapServer['authObjectType'])) {
259           return;
260         }
261         
262         $this -> LSuserObject = new $this -> ldapServer['authObjectType']();
263         $this -> LSuserObject -> loadData($this -> dn);
264         
265         if ( !$this -> cacheLSprofiles() || isset($_REQUEST['LSsession_refresh']) ) {
266           $this -> loadLSaccess();
267         }
268         
269         $GLOBALS['Smarty'] -> assign('LSsession_username',$this -> LSuserObject -> getDisplayValue());
270         
271         if ($_POST['LSsession_topDn']) {
272           if ($this -> validSubDnLdapServer($_POST['LSsession_topDn'])) {
273             $this -> topDn = $_POST['LSsession_topDn'];
274             $_SESSION['LSsession']['topDn'] = $_POST['LSsession_topDn'];
275           } // end if
276         } // end if
277         
278         return true;
279         
280       }
281       else {
282         // Session inexistante
283         $recoveryPasswordInfos=array();
284
285         if (isset($_POST['LSsession_user'])) {
286           if (isset($_POST['LSsession_ldapserver'])) {
287             $this -> setLdapServer($_POST['LSsession_ldapserver']);
288           }
289           else {
290             $this -> setLdapServer(0);
291           }
292           
293           // Connexion au serveur LDAP
294               if ($this -> LSldapConnect()) {
295
296             // topDn
297             if ( $_POST['LSsession_topDn'] != '' ){
298               $this -> topDn = $_POST['LSsession_topDn'];
299             }
300             else {
301               $this -> topDn = $this -> ldapServer['ldap_config']['basedn'];
302             }
303             $_SESSION['LSsession_topDn']=$this -> topDn;
304
305             if ( $this -> loadLSobject($this -> ldapServer['authObjectType']) ) {
306               $authobject = new $this -> ldapServer['authObjectType']();
307               $find=true;
308               if (isset($_GET['recoveryHash'])) {
309                 $filter=$this -> ldapServer['recoverPassword']['recoveryHashAttr']."=".$_GET['recoveryHash'];
310                 $result = $authobject -> listObjects($filter,$this -> topDn);
311                 $nbresult=count($result);
312                 if ($nbresult==1) {
313                   $rdn = $result[0] -> getValue('rdn');
314                   $rdn = $rdn[0];
315                   $_POST['LSsession_user'] = $rdn;
316                   $find=false;
317                 }
318               }
319               if ($find) {
320                 $result = $authobject -> searchObject($_POST['LSsession_user'],$this -> topDn);
321                 $nbresult=count($result);
322               }
323               if ($nbresult==0) {
324                 // identifiant incorrect
325                 LSdebug('identifiant incorrect');
326                 $GLOBALS['LSerror'] -> addErrorCode('LSsession_06');
327               }
328               else if ($nbresult>1) {
329                 // duplication d'authentité
330                 $GLOBALS['LSerror'] -> addErrorCode('LSsession_07');
331               }
332               else {
333                 if (isset($_GET['LSsession_recoverPassword'])) {
334                   LSdebug('Recover : Id trouvé');
335                   if ($this -> ldapServer['recoverPassword']) {
336                     if ($this -> loadLSaddon('mail')) {
337                       LSdebug('Récupération active');
338                       $user=$result[0];
339                       $emailAddress = $user -> getValue($this -> ldapServer['recoverPassword']['mailAttr']);
340                       $emailAddress = $emailAddress[0];
341                       
342                       // Header des mails
343                       $sendParams=array();
344                       if ($this -> ldapServer['recoverPassword']['recoveryEmailSender']) {
345                         $sendParams['From']=$this -> ldapServer['recoverPassword']['recoveryEmailSender'];
346                       }
347                       
348                       if (checkEmail($emailAddress)) {
349                         LSdebug('Email : '.$emailAddress);
350                         $this -> dn = $user -> getDn();
351                         // 1ère étape : envoie du recoveryHash
352                         if (!isset($_GET['recoveryHash'])) {
353                           // Generer un hash
354                           $rdn=$user -> getValue('rdn');
355                           $rdn = $rdn[0];
356                           $recovery_hash = md5($rdn . strval(time()) . strval(rand()));
357                           
358                           $lostPasswdForm = $user -> getForm('lostPassword');
359                           $lostPasswdForm -> setPostData(
360                             array(
361                               $this -> ldapServer['recoverPassword']['recoveryHashAttr'] => $recovery_hash
362                             )
363                             ,true
364                           );
365                           
366                           if($lostPasswdForm -> validate()) {
367                             if ($user -> updateData('lostPassword')) {
368                               // recoveryHash de l'utilisateur mis à jour
369                               if ($_SERVER['HTTPS']=='on') {
370                                 $recovery_url='https://';
371                               }
372                               else {
373                                 $recovery_url='http://';
374                               }
375                               $recovery_url .= $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'&recoveryHash='.$recovery_hash;
376
377                               if (
378                                 sendMail(
379                                   $emailAddress,
380                                   $this -> ldapServer['recoverPassword']['recoveryHashMail']['subject'],
381                                   getFData($this -> ldapServer['recoverPassword']['recoveryHashMail']['msg'],$recovery_url),
382                                   $sendParams
383                                 )
384                               ){
385                                 // Mail a bien été envoyé
386                                 $recoveryPasswordInfos['recoveryHashMail']=$emailAddress;
387                               }
388                               else {
389                                 // Problème durant l'envoie du mail
390                                 LSdebug("Problème durant l'envoie du mail");
391                                 $GLOBALS['LSerror'] -> addErrorCode('LSsession_20',7);
392                               }
393                             }
394                             else {
395                               // Erreur durant la mise à jour de l'objet
396                               LSdebug("Erreur durant la mise à jour de l'objet");
397                               $GLOBALS['LSerror'] -> addErrorCode('LSsession_20',6);
398                             }
399                           }
400                           else {
401                             // Erreur durant la validation du formulaire de modification de perte de password
402                             LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
403                             $GLOBALS['LSerror'] -> addErrorCode('LSsession_20',5);
404                           }
405                         }
406                         // 2nd étape : génération du mot de passe + envoie par mail
407                         else {
408                           $attr=$user -> attrs[$this -> ldapServer['authObjectTypeAttrPwd']];
409                           if ($attr instanceof LSattribute) {
410                             $mdp = generatePassword($attr -> config['html_options']['chars'],$attr -> config['html_options']['lenght']);
411                             LSdebug('Nvx mpd : '.$mdp);
412                             $lostPasswdForm = $user -> getForm('lostPassword');
413                             $lostPasswdForm -> setPostData(
414                               array(
415                                 $this -> ldapServer['recoverPassword']['recoveryHashAttr'] => array(''),
416                                 $this -> ldapServer['authObjectTypeAttrPwd'] => array($mdp)
417                               )
418                               ,true
419                             );
420                             if($lostPasswdForm -> validate()) {
421                               if ($user -> updateData('lostPassword')) {
422                                 if (
423                                   sendMail(
424                                     $emailAddress,
425                                     $this -> ldapServer['recoverPassword']['newPasswordMail']['subject'],
426                                     getFData($this -> ldapServer['recoverPassword']['newPasswordMail']['msg'],$mdp),
427                                     $sendParams
428                                   )
429                                 ){
430                                   // Mail a bien été envoyé
431                                   $recoveryPasswordInfos['newPasswordMail']=$emailAddress;
432                                 }
433                                 else {
434                                   // Problème durant l'envoie du mail
435                                   LSdebug("Problème durant l'envoie du mail");
436                                   $GLOBALS['LSerror'] -> addErrorCode('LSsession_20',4);
437                                 }
438                               }
439                               else {
440                                 // Erreur durant la mise à jour de l'objet
441                                 LSdebug("Erreur durant la mise à jour de l'objet");
442                                 $GLOBALS['LSerror'] -> addErrorCode('LSsession_20',3);
443                               }
444                             }
445                             else {
446                               // Erreur durant la validation du formulaire de modification de perte de password
447                               LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
448                               $GLOBALS['LSerror'] -> addErrorCode('LSsession_20',2);
449                             }
450                           }
451                           else {
452                             // l'attribut password n'existe pas
453                             LSdebug("L'attribut password n'existe pas");
454                             $GLOBALS['LSerror'] -> addErrorCode('LSsession_20',1);
455                           }
456                         }
457                       }
458                       else {
459                         $GLOBALS['LSerror'] -> addErrorCode('LSsession_19');
460                       }
461                     }
462                   }
463                   else {
464                     $GLOBALS['LSerror'] -> addErrorCode('LSsession_18');
465                   }
466                 }
467                 else {
468                   if ( $this -> checkUserPwd($result[0],$_POST['LSsession_pwd']) ) {
469                     // Authentification réussi
470                     $this -> LSuserObject = $result[0];
471                     $this -> dn = $result[0]->getValue('dn');
472                     $this -> rdn = $_POST['LSsession_user'];
473                     $this -> loadLSprofiles();
474                     $this -> loadLSaccess();
475                     $GLOBALS['Smarty'] -> assign('LSsession_username',$this -> LSuserObject -> getDisplayValue());
476                     $_SESSION['LSsession']=get_object_vars($this);
477                     return true;
478                   }
479                   else {
480                     $GLOBALS['LSerror'] -> addErrorCode('LSsession_06');
481                     LSdebug('mdp incorrect');
482                   }
483                 }
484               }
485             }
486             else {
487               $GLOBALS['LSerror'] -> addErrorCode('LSsession_10');
488             }
489           }
490           else {
491             $GLOBALS['LSerror'] -> addErrorCode('LSsession_09');
492           }
493         }
494         if ($this -> ldapServerId) {
495           $GLOBALS['Smarty'] -> assign('ldapServerId',$this -> ldapServerId);
496         }
497         $GLOBALS['Smarty'] -> assign('topDn',$this -> topDn);
498         if (isset($_GET['LSsession_recoverPassword'])) {
499           $this -> displayRecoverPasswordForm($recoveryPasswordInfos);
500         }
501         else {
502           $this -> displayLoginForm();
503         }
504         return;
505       }
506   }
507
508  /**
509   * Modifie l'utilisateur connecté à la volé
510   * 
511   * @param[in] $object Mixed  L'objet Ldap du nouvel utilisateur
512   *                           le type doit correspondre à
513   *                           $this -> ldapServer['authObjectType']
514   * 
515   * @retval boolean True en cas de succès, false sinon
516   */
517  function changeAuthUser($object) {
518   if ($object instanceof $this -> ldapServer['authObjectType']) {
519     $this -> dn = $object -> getDn();
520     $rdn = $object -> getValue('rdn');
521     if(is_array($rdn)) {
522       $rdn = $rdn[0];
523     }
524     $this -> rdn = $rdn;
525     $this -> LSuserObject = $object;
526     
527     if($this -> loadLSprofiles()) {
528       $this -> loadLSaccess();
529       $_SESSION['LSsession']=get_object_vars($this);
530       return true;
531     }
532   }
533   return;
534  }
535
536  /**
537   * Définition du serveur Ldap de la session
538   *
539   * Définition du serveur Ldap de la session Ã  partir de son ID dans 
540   * le tableau $GLOBALS['LSconfig']['ldap_servers'].
541   *
542   * @param[in] integer Index du serveur Ldap
543   *
544   * @retval boolean True sinon false.
545   */
546   function setLdapServer($id) {
547     if ( isset($GLOBALS['LSconfig']['ldap_servers'][$id]) ) {
548       $this -> ldapServerId = $id;
549       $this -> ldapServer=$GLOBALS['LSconfig']['ldap_servers'][$id];
550       return true;
551     }
552     else {
553       return;
554     }
555   }
556
557  /**
558   * Connexion au serveur Ldap
559   *
560   * @retval boolean True sinon false.
561   */
562   function LSldapConnect() {
563     if ($this -> ldapServer) {
564       @include_once($GLOBALS['LSconfig']['NetLDAP2']);
565       if (!$this -> loadLSclass('LSldap')) {
566         return;
567       }
568       $GLOBALS['LSldap'] = @new LSldap($this -> ldapServer['ldap_config']);
569       if ($GLOBALS['LSldap'] -> isConnected()) {
570         return true;
571       }
572       else {
573         return;
574       }
575     }
576     else {
577       $GLOBALS['LSerror'] -> addErrorCode('LSsession_03');
578       return;
579     }
580   }
581
582  /**
583   * Retourne les sous-dns du serveur Ldap courant
584   *
585   * @retval mixed Tableau des subDn, false si une erreur est survenue.
586   */
587   function getSubDnLdapServer() {
588     if ($this -> cacheSudDn() && isset($this -> _subDnLdapServer[$this -> ldapServerId])) {
589       return $this -> _subDnLdapServer[$this -> ldapServerId];
590     }
591     if (!isset($this ->ldapServer['subDn'])) {
592       return;
593     }
594     if ( !is_array($this ->ldapServer['subDn']) ) {
595       return;
596     }
597     $return=array();
598     foreach($this ->ldapServer['subDn'] as $subDn_name => $subDn_config) {
599       if ($subDn_name == 'LSobject') {
600         if (is_array($subDn_config)) {
601           foreach($subDn_config as $LSobject_name => $LSoject_config) {
602             if ($LSoject_config['basedn']) {
603               $basedn = $LSoject_config['basedn'];
604             }
605             else {
606               $basedn = NULL;
607             }
608             if ($LSoject_config['displayValue']) {
609               $displayValue = $LSoject_config['displayValue'];
610             }
611             else {
612               $displayValue = NULL;
613             }
614             if( $this -> loadLSobject($LSobject_name) ) {
615               if ($subdnobject = new $LSobject_name()) {
616                 $tbl_return = $subdnobject -> getSelectArray(NULL,$basedn,$displayValue);
617                 if (is_array($tbl_return)) {
618                   $return=array_merge($return,$tbl_return);
619                 }
620                 else {
621                   $GLOBALS['LSerror'] -> addErrorCode('LSsession_17',3);
622                 }
623               }
624               else {
625                 $GLOBALS['LSerror'] -> addErrorCode('LSsession_17',2);
626               }
627             }
628           }
629         }
630         else {
631           $GLOBALS['LSerror'] -> addErrorCode('LSsession_17',1);
632         }
633       }
634       else {
635         if ((isCompatibleDNs($subDn_config['dn'],$this -> ldapServer['ldap_config']['basedn']))&&($subDn_config['dn']!="")) {
636           $return[$subDn_config['dn']] = $subDn_name;
637         }
638       }
639     }
640     if ($this -> cacheSudDn()) {
641       $this -> _subDnLdapServer[$this -> ldapServerId]=$return;
642       $_SESSION['LSsession_subDnLdapServer'] = $this -> _subDnLdapServer;
643     }
644     return $return;
645   }
646   
647   /**
648    * Retourne la liste de subDn du serveur Ldap utilise
649    * trié par la profondeur dans l'arboressence (ordre décroissant)
650    * 
651    * @return array() Tableau des subDn trié
652    */  
653   function getSortSubDnLdapServer() {
654     $subDnLdapServer = $this  -> getSubDnLdapServer();
655     if (!$subDnLdapServer) {
656       return array();
657     }
658     uksort($subDnLdapServer,"compareDn");
659     return $subDnLdapServer;
660   }
661
662  /**
663   * Retourne les options d'une liste déroulante pour le choix du topDn
664   * de connexion au serveur Ldap
665   *
666   * Liste les subdn ($this ->ldapServer['subDn'])
667   *
668   * @retval string Les options (<option>) pour la sélection du topDn.
669   */
670   function getSubDnLdapServerOptions($selected=NULL) {
671     $list = $this -> getSubDnLdapServer();
672     if ($list) {
673       asort($list);
674       $display='';
675       foreach($list as $dn => $txt) {
676         if ($selected && ($selected==$dn)) {
677           $selected_txt = ' selected';
678         }
679         else {
680           $selected_txt = '';
681         }
682         $display.="<option value=\"".$dn."\"$selected_txt>".$txt."</option>\n"; 
683       }
684       return $display;
685     }
686     return;
687   }
688
689   function validSubDnLdapServer($subDn) {
690     $listTopDn = $this -> getSubDnLdapServer();
691     if(is_array($listTopDn)) {
692       foreach($listTopDn as $dn => $txt) {
693         if ($subDn==$dn) {
694           return true;
695         } // end if
696       } // end foreach
697     } // end if
698     return;
699   }
700
701  /**
702   * Test un couple LSobject/pwd
703   *
704   * Test un bind sur le serveur avec le dn de l'objet et le mot de passe fourni.
705   *
706   * @param[in] LSobject L'object "user" pour l'authentification
707   * @param[in] string Le mot de passe Ã  tester
708   *
709   * @retval boolean True si l'authentification Ã  réussi, false sinon.
710   */
711   function checkUserPwd($object,$pwd) {
712     return $GLOBALS['LSldap'] -> checkBind($object -> getValue('dn'),$pwd);
713   }
714
715  /**
716   * Affiche le formulaire de login
717   *
718   * Défini les informations pour le template Smarty du formulaire de login.
719   *
720   * @retval void
721   */
722   function displayLoginForm() {
723     $GLOBALS['Smarty'] -> assign('pagetitle',_('Connexion'));
724     if (isset($_GET['LSsession_logout'])) {
725       $GLOBALS['Smarty'] -> assign('loginform_action','index.php');
726     }
727     else {
728       $GLOBALS['Smarty'] -> assign('loginform_action',$_SERVER['REQUEST_URI']);
729     }
730     if (count($GLOBALS['LSconfig']['ldap_servers'])==1) {
731       $GLOBALS['Smarty'] -> assign('loginform_ldapserver_style','style="display: none"');
732     }
733     $GLOBALS['Smarty'] -> assign('loginform_label_ldapserver',_('Serveur LDAP'));
734     $ldapservers_name=array();
735     $ldapservers_index=array();
736     foreach($GLOBALS['LSconfig']['ldap_servers'] as $id => $infos) {
737       $ldapservers_index[]=$id;
738       $ldapservers_name[]=$infos['name'];
739     }
740     $GLOBALS['Smarty'] -> assign('loginform_ldapservers_name',$ldapservers_name);
741     $GLOBALS['Smarty'] -> assign('loginform_ldapservers_index',$ldapservers_index);
742
743     $GLOBALS['Smarty'] -> assign('loginform_label_level',_('Niveau'));
744     $GLOBALS['Smarty'] -> assign('loginform_label_user',_('Identifiant'));
745     $GLOBALS['Smarty'] -> assign('loginform_label_pwd',_('Mot de passe'));
746     $GLOBALS['Smarty'] -> assign('loginform_label_submit',_('Connexion'));
747     $GLOBALS['Smarty'] -> assign('loginform_label_recoverPassword',_('Mot de passe oublié ?'));
748     
749     $this -> setTemplate('login.tpl');
750     $this -> addJSscript('LSsession_login.js');
751   }
752
753  /**
754   * Affiche le formulaire de récupération de mot de passe
755   *
756   * Défini les informations pour le template Smarty du formulaire de 
757   * récupération de mot de passe
758   * 
759   * @param[in] $infos array() Information sur le status du processus de 
760   *                           recouvrement de mot de passe
761   *
762   * @retval void
763   */
764   function displayRecoverPasswordForm($recoveryPasswordInfos) {
765     $GLOBALS['Smarty'] -> assign('pagetitle',_('Récupération de votre mot de passe'));
766     $GLOBALS['Smarty'] -> assign('recoverpasswordform_action','index.php?LSsession_recoverPassword');
767     
768     if (count($GLOBALS['LSconfig']['ldap_servers'])==1) {
769       $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapserver_style','style="display: none"');
770     }
771     
772     $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_ldapserver',_('Serveur LDAP'));
773     $ldapservers_name=array();
774     $ldapservers_index=array();
775     foreach($GLOBALS['LSconfig']['ldap_servers'] as $id => $infos) {
776       $ldapservers_index[]=$id;
777       $ldapservers_name[]=$infos['name'];
778     }
779     $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapservers_name',$ldapservers_name);
780     $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapservers_index',$ldapservers_index);
781
782     $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_user',_('Identifiant'));
783     $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_submit',_('Valider'));
784     $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_back',_('Retour'));
785     
786     $recoverpassword_msg = _('Veuillez saisir votre identifiant pour poursuivre le processus de récupération de votre mot de passe');
787     
788     if (isset($recoveryPasswordInfos['recoveryHashMail'])) {
789       $recoverpassword_msg = getFData(
790         _("Un mail vient de vous être envoyé à l'adresse %{mail}. " .
791         "Merci de suivre les indications contenus dans ce mail."),
792         $recoveryPasswordInfos['recoveryHashMail']
793       );
794     }
795     
796     if (isset($recoveryPasswordInfos['newPasswordMail'])) {
797       $recoverpassword_msg = getFData(
798         _("Votre nouveau mot de passe vient de vous être envoyé à l'adresse %{mail}. "),
799         $recoveryPasswordInfos['newPasswordMail']
800       );
801     }
802     
803     $GLOBALS['Smarty'] -> assign('recoverpassword_msg',$recoverpassword_msg);
804     
805     $this -> setTemplate('recoverpassword.tpl');
806     $this -> addJSscript('LSsession_recoverPassword.js');
807   }
808
809  /**
810   * Défini le template Smarty Ã  utiliser
811   *
812   * Remarque : les fichiers de templates doivent se trouver dans le dossier 
813   * templates/.
814   *
815   * @param[in] string Le nom du fichier de template
816   *
817   * @retval void
818   */
819   function setTemplate($template) {
820     $this -> template = $template;
821   }
822
823  /**
824   * Ajoute un script JS au chargement de la page
825   *
826   * Remarque : les scripts doivents Ãªtre dans le dossier LS_JS_DIR.
827   *
828   * @param[in] $script Le nom du fichier de script Ã  charger.
829   *
830   * @retval void
831   */
832   function addJSscript($file,$path=NULL) {
833     $script=array(
834       'file' => $file,
835       'path' => $path
836     );
837     $this -> JSscripts[$path.$file]=$script;
838   }
839
840  /**
841   * Ajouter un paramètre de configuration Javascript
842   * 
843   * @param[in] $name string Nom de la variable de configuration
844   * @param[in] $val mixed Valeur de la variable de configuration
845   *
846   * @retval void
847   */
848   function addJSconfigParam($name,$val) {
849     $this -> _JSconfigParams[$name]=$val;
850   }
851
852  /**
853   * Ajoute une feuille de style au chargement de la page
854   *
855   * Remarque : les scripts doivents Ãªtre dans le dossier LS_CSS_DIR.
856   *
857   * @param[in] $script Le nom du fichier css Ã  charger.
858   *
859   * @retval void
860   */
861   function addCssFile($file,$path=NULL) {
862     $cssFile=array(
863       'file' => $file,
864       'path' => $path
865     );
866     $this -> CssFiles[$path.$file]=$cssFile;
867   }
868
869  /**
870   * Affiche le template Smarty
871   *
872   * Charge les dépendances et affiche le template Smarty
873   *
874   * @retval void
875   */
876   function displayTemplate() {
877     // JS
878     $JSscript_txt='';
879     foreach ($GLOBALS['defaultJSscipts'] as $script) {
880       $JSscript_txt.="<script src='".LS_JS_DIR.$script."' type='text/javascript'></script>\n";
881     }
882
883     foreach ($this -> JSscripts as $script) {
884       if (!$script['path']) {
885         $script['path']=LS_JS_DIR;
886       }
887       else {
888         $script['path'].='/';
889       }
890       $JSscript_txt.="<script src='".$script['path'].$script['file']."' type='text/javascript'></script>\n";
891     }
892
893     $GLOBALS['Smarty'] -> assign('LSjsConfig',json_encode($this -> _JSconfigParams));
894     
895     if ($GLOBALS['LSdebug']['active']) {
896       $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 1;</script>\n";
897     }
898     else {
899       $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 0;</script>\n";
900     }
901     
902     $GLOBALS['Smarty'] -> assign('LSsession_js',$JSscript_txt);
903
904     // Css
905     $this -> addCssFile("LSdefault.css");
906     $Css_txt='';
907     foreach ($this -> CssFiles as $file) {
908       if (!$file['path']) {
909         $file['path']=LS_CSS_DIR.'/';
910       }
911       $Css_txt.="<link rel='stylesheet' type='text/css' href='".$file['path'].$file['file']."' />\n";
912     }
913     $GLOBALS['Smarty'] -> assign('LSsession_css',$Css_txt);
914   
915     if (isset($this -> LSaccess[$this -> topDn])) {
916       $GLOBALS['Smarty'] -> assign('LSaccess',$this -> LSaccess[$this -> topDn]);
917     }
918     
919     // Niveau
920     $listTopDn = $this -> getSubDnLdapServer();
921     if (is_array($listTopDn)) {
922       asort($listTopDn);
923       $GLOBALS['Smarty'] -> assign('label_level',$this -> getSubDnLabel());
924       $GLOBALS['Smarty'] -> assign('_refresh',_('Rafraîchir'));
925       $LSsession_topDn_index = array();
926       $LSsession_topDn_name = array();
927       foreach($listTopDn as $index => $name) {
928         $LSsession_topDn_index[]  = $index;
929         $LSsession_topDn_name[]   = $name;
930       }
931       $GLOBALS['Smarty'] -> assign('LSsession_subDn_indexes',$LSsession_topDn_index);
932       $GLOBALS['Smarty'] -> assign('LSsession_subDn_names',$LSsession_topDn_name);
933       $GLOBALS['Smarty'] -> assign('LSsession_subDn',$this -> topDn);
934       $GLOBALS['Smarty'] -> assign('LSsession_subDnName',$this -> getSubDnName());
935     }
936
937     // Infos
938     if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
939       $txt_infos="<ul>\n";
940       foreach($_SESSION['LSsession_infos'] as $info) {
941         $txt_infos.="<li>$info</li>\n";
942       }
943       $txt_infos.="</ul>\n";
944       $GLOBALS['Smarty'] -> assign('LSinfos',$txt_infos);
945       $_SESSION['LSsession_infos']=array();
946     }
947     
948     if ($this -> ajaxDisplay) {
949       $GLOBALS['Smarty'] -> assign('LSerror_txt',$GLOBALS['LSerror']->getErrors());
950       $GLOBALS['Smarty'] -> assign('LSdebug_txt',LSdebug_print(true));
951     }
952     else {
953       $GLOBALS['LSerror'] -> display();
954       LSdebug_print();
955     }
956     if (!$this -> template)
957       $this -> setTemplate('empty.tpl');
958     $GLOBALS['Smarty'] -> display($this -> template);
959   }
960   
961  /**
962   * Affiche un retour Ajax
963   *
964   * @retval void
965   */
966   function displayAjaxReturn($data=array()) {
967     $data['LSjsConfig'] = $this -> _JSconfigParams;
968     
969     // Infos
970     if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
971       $txt_infos="<ul>\n";
972       foreach($_SESSION['LSsession_infos'] as $info) {
973         $txt_infos.="<li>$info</li>\n";
974       }
975       $txt_infos.="</ul>\n";
976       $data['LSinfos'] = $txt_infos;
977       $_SESSION['LSsession_infos']=array();
978     }
979     
980     if ($GLOBALS['LSerror']->errorsDefined()) {
981       $data['LSerror'] = $GLOBALS['LSerror']->getErrors();
982     }
983
984     if (isset($_REQUEST['imgload'])) {
985       $data['imgload'] = $_REQUEST['imgload'];
986     }
987
988     if (LSdebugDefined()) {
989       $data['LSdebug'] = LSdebug_print(true);
990     }
991
992     echo json_encode($data);  
993   }
994  
995  /**
996   * Retournne un template Smarty compilé
997   *
998   * @param[in] string $template Le template à retourner
999   * @param[in] array $variables Variables Smarty à assigner avant l'affichage
1000   * 
1001   * @retval string Le HTML compilé du template
1002   */
1003   function fetchTemplate($template,$variables=array()) {
1004     foreach($variables as $name => $val) {
1005       $GLOBALS['Smarty'] -> assign($name,$val);
1006     }
1007     return $GLOBALS['Smarty'] -> fetch($template);
1008   }
1009   
1010   /**
1011    * Charge les droits LS de l'utilisateur
1012    * 
1013    * @retval boolean True si le chargement Ã  réussi, false sinon.
1014    **/
1015   function loadLSprofiles() {
1016     if (is_array($this -> ldapServer['LSprofiles'])) {
1017       foreach ($this -> ldapServer['LSprofiles'] as $profile => $profileInfos) {
1018         if (is_array($profileInfos)) {
1019           foreach ($profileInfos as $topDn => $rightsInfos) {
1020             /*
1021              * If $topDn == 'LSobject', we search for each LSobject type to find
1022              * all items on witch the user will have powers.
1023              */
1024             if ($topDn == 'LSobjects') {
1025               if (is_array($rightsInfos)) {
1026                 foreach ($rightsInfos as $LSobject => $listInfos) {
1027                   if ($this -> loadLSobject($LSobject)) {
1028                     if ($object = new $LSobject()) {
1029                       if ($listInfos['filter']) {
1030                         $filter = $this -> LSuserObject -> getFData($listInfos['filter']);
1031                       }
1032                       else {
1033                         $filter = $listInfos['attr'].'='.$this -> LSuserObject -> getFData($listInfos['attr_value']);
1034                       }
1035                       $list = $object -> search($filter,$listInfos['basedn'],$listInfos['params']);
1036                       foreach($list as $obj) {
1037                         $this -> LSprofiles[$profile][] = $obj['dn'];
1038                       }
1039                     }
1040                     else {
1041                       LSdebug('Impossible de créer l\'objet de type : '.$LSobject);
1042                     }
1043                   }
1044                 }
1045               }
1046               else {
1047                 LSdebug('LSobjects => [] doit etre un tableau');
1048               }
1049             }
1050             else {
1051               if (is_array($rightsInfos)) {
1052                 foreach($rightsInfos as $dn => $conf) {
1053                   if ((isset($conf['attr'])) && (isset($conf['LSobject']))) {
1054                     if( $this -> loadLSobject($conf['LSobject']) ) {
1055                       if ($object = new $conf['LSobject']()) {
1056                         if ($object -> loadData($dn)) {
1057                           $listDns=$object -> getValue($conf['attr']);
1058                           $valKey = (isset($conf['attr_value']))?$conf['attr_value']:'%{dn}';
1059                           $val = $this -> LSuserObject -> getFData($valKey);
1060                           if (is_array($listDns)) {
1061                             if (in_array($val,$listDns)) {
1062                               $this -> LSprofiles[$profile][] = $topDn;
1063                             }
1064                           }
1065                         }
1066                         else {
1067                           LSdebug('Impossible de chargé le dn : '.$dn);
1068                         }
1069                       }
1070                       else {
1071                         LSdebug('Impossible de créer l\'objet de type : '.$conf['LSobject']);
1072                       }
1073                     }
1074                   }
1075                   else {
1076                     if ($this -> dn == $dn) {
1077                       $this -> LSprofiles[$profile][] = $topDn;
1078                     }
1079                   }
1080                 }
1081               }
1082               else {
1083                 if ( $this -> dn == $rightsInfos ) {
1084                   $this -> LSprofiles[$profile][] = $topDn;
1085                 }
1086               }
1087             } // fin else ($topDn == 'LSobjects')
1088           } // fin foreach($profileInfos)
1089         } // fin is_array($profileInfos)
1090       } // fin foreach LSprofiles
1091       LSdebug($this -> LSprofiles);
1092       return true;
1093     }
1094     else {
1095       return;
1096     }
1097   }
1098   
1099   /**
1100    * Charge les droits d'accès de l'utilisateur pour construire le menu de l'interface
1101    *
1102    * @retval void
1103    */
1104   function loadLSaccess() {
1105     $LSaccess=array();
1106     if (is_array($this -> ldapServer['subDn'])) {
1107       foreach($this -> ldapServer['subDn'] as $name => $config) {
1108         if ($name=='LSobject') {
1109           if (is_array($config)) {
1110
1111             // Définition des subDns 
1112             foreach($config as $objectType => $objectConf) {
1113               if ($this -> loadLSobject($objectType)) {
1114                 if ($subdnobject = new $objectType()) {
1115                   $tbl = $subdnobject -> getSelectArray();
1116                   if (is_array($tbl)) {
1117                     // Définition des accès
1118                     $access=array();
1119                     if (is_array($objectConf['LSobjects'])) {
1120                       foreach($objectConf['LSobjects'] as $type) {
1121                         if ($this -> loadLSobject($type)) {
1122                           if ($this -> canAccess($type)) {
1123                             $access[$type] = $GLOBALS['LSobjects'][$type]['label'];
1124                           }
1125                         }
1126                       }
1127                     }
1128                     foreach($tbl as $dn => $dn_name) {
1129                       $LSaccess[$dn]=$access;
1130                     }
1131                   }
1132                 }
1133               }
1134             }
1135           }
1136         }
1137         else {
1138           if ((isCompatibleDNs($this -> ldapServer['ldap_config']['basedn'],$config['dn']))&&($config['dn']!='')) {
1139             $access=array();
1140             if (is_array($config['LSobjects'])) {
1141               foreach($config['LSobjects'] as $objectType) {
1142                 if ($this -> loadLSobject($objectType)) {
1143                   if ($this -> canAccess($objectType)) {
1144                     $access[$objectType] = $GLOBALS['LSobjects'][$objectType]['label'];
1145                   }
1146                 }
1147               }
1148             }
1149             $LSaccess[$config['dn']]=$access;
1150           }
1151         }
1152       }
1153     }
1154     else {
1155       if(is_array($this -> ldapServer['LSaccess'])) {
1156         $access=array();
1157         foreach($this -> ldapServer['LSaccess'] as $objectType) {
1158           if ($this -> loadLSobject($objectType)) {
1159             if ($this -> canAccess($objectType)) {
1160                 $access[$objectType] = $GLOBALS['LSobjects'][$objectType]['label'];
1161             }
1162           }
1163         }
1164         $LSaccess[$this -> topDn] = $access;
1165       }
1166     }
1167     foreach($LSaccess as $dn => $access) {
1168       $LSaccess[$dn] = array_merge(
1169         array(
1170           'SELF' => _('Mon compte')
1171         ),
1172         $access
1173       );
1174     }
1175     
1176     $this -> LSaccess = $LSaccess;
1177     $_SESSION['LSsession']['LSaccess'] = $LSaccess;
1178   }
1179   
1180   /**
1181    * Dit si l'utilisateur est du profil pour le DN spécifié
1182    *
1183    * @param[in] string $profile de l'objet
1184    * @param[in] string $dn DN de l'objet
1185    * 
1186    * @retval boolean True si l'utilisateur est du profil sur l'objet, false sinon.
1187    */
1188   function isProfile($dn,$profile) {
1189     if (is_array($this -> LSprofiles[$profile])) {
1190       foreach($this -> LSprofiles[$profile] as $topDn) {
1191         if($dn == $topDn) {
1192           return true;
1193         }
1194         else if ( isCompatibleDNs($dn,$topDn) ) {
1195           return true;
1196         }
1197       }
1198     }
1199     return;
1200   }
1201   
1202   /**
1203    * Retourne qui est l'utilisateur par rapport Ã  l'object
1204    *
1205    * @param[in] string Le DN de l'objet
1206    * 
1207    * @retval string 'admin'/'self'/'user' pour Admin , l'utilisateur lui même ou un simple utilisateur
1208    */
1209   function whoami($dn) {
1210     $retval = array('user');
1211     
1212     foreach($this -> LSprofiles as $profile => $infos) {
1213       if($this -> isProfile($dn,$profile)) {
1214        $retval[]=$profile;
1215       }
1216     }
1217     
1218     if ($this -> dn == $dn) {
1219       $retval[]='self';
1220     }
1221     
1222     return $retval;
1223   }
1224   
1225   /**
1226    * Retourne le droit de l'utilisateur Ã  accèder Ã  un objet
1227    * 
1228    * @param[in] string $LSobject Le type de l'objet
1229    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1230    * @param[in] string $right Le type de droit d'accès Ã  tester ('r'/'w')
1231    * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1232    *
1233    * @retval boolean True si l'utilisateur a accès, false sinon
1234    */
1235   function canAccess($LSobject,$dn=NULL,$right=NULL,$attr=NULL) {
1236     if (!$this -> loadLSobject($LSobject)) {
1237       return;
1238     }
1239     if ($dn) {
1240       $whoami = $this -> whoami($dn);
1241       if ($dn==$this -> LSuserObject -> getValue('dn')) {
1242         if (!$this -> in_menu('SELF')) {
1243           return;
1244         }
1245       }
1246       else {
1247         $obj = new $LSobject();
1248         $obj -> dn = $dn;
1249         if (!$this -> in_menu($LSobject,$obj -> getSubDnValue())) {
1250           return;
1251         }
1252       }
1253     }
1254     else {
1255       $objectdn=$GLOBALS['LSobjects'][$LSobject]['container_dn'].','.$this -> topDn;
1256       $whoami = $this -> whoami($objectdn);
1257     }
1258     
1259     // Pour un attribut particulier
1260     if ($attr) {
1261       if ($attr=='rdn') {
1262         $attr=$GLOBALS['LSobjects'][$LSobject]['rdn'];
1263       }
1264       if (!isset($GLOBALS['LSobjects'][$LSobject]['attrs'][$attr])) {
1265         return;
1266       }
1267
1268       $r = 'n';
1269       foreach($whoami as $who) {
1270         $nr = $GLOBALS['LSobjects'][$LSobject]['attrs'][$attr]['rights'][$who];
1271         if($nr == 'w') {
1272           $r = 'w';
1273         }
1274         else if($nr == 'r') {
1275           if ($r=='n') {
1276             $r='r';
1277           }
1278         }
1279       }
1280       
1281       if (($right=='r')||($right=='w')) {
1282         if ($r==$right) {
1283           return true;
1284         }
1285         return;
1286       }
1287       else {
1288         if ( ($r=='r') || ($r=='w') ) {
1289           return true;
1290         }
1291         return;
1292       }
1293     }
1294     
1295     // Pour un attribut quelconque
1296     if (is_array($GLOBALS['LSobjects'][$LSobject]['attrs'])) {
1297       if (($right=='r')||($right=='w')) {
1298         foreach($whoami as $who) {
1299           foreach ($GLOBALS['LSobjects'][$LSobject]['attrs'] as $attr_name => $attr_config) {
1300             if ($attr_config['rights'][$who]==$right) {
1301               return true;
1302             }
1303           }
1304         }
1305       }
1306       else {
1307         foreach($whoami as $who) {
1308           foreach ($GLOBALS['LSobjects'][$LSobject]['attrs'] as $attr_name => $attr_config) {
1309             if ( ($attr_config['rights'][$who]=='r') || ($attr_config['rights'][$who]=='w') ) {
1310               return true;
1311             }
1312           }
1313         }
1314       }
1315     }
1316     return;
1317   }
1318   
1319   /**
1320    * Retourne le droit de l'utilisateur Ã  editer Ã  un objet
1321    * 
1322    * @param[in] string $LSobject Le type de l'objet
1323    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1324    * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1325    *
1326    * @retval boolean True si l'utilisateur a accès, false sinon
1327    */
1328   function canEdit($LSobject,$dn=NULL,$attr=NULL) {
1329     return $this -> canAccess($LSobject,$dn,'w',$attr);
1330   }
1331
1332   /**
1333    * Retourne le droit de l'utilisateur Ã  supprimer un objet
1334    * 
1335    * @param[in] string $LSobject Le type de l'objet
1336    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1337    *
1338    * @retval boolean True si l'utilisateur a accès, false sinon
1339    */  
1340   function canRemove($LSobject,$dn) {
1341     return $this -> canAccess($LSobject,$dn,'w','rdn');
1342   }
1343   
1344   /**
1345    * Retourne le droit de l'utilisateur Ã  créer un objet
1346    * 
1347    * @param[in] string $LSobject Le type de l'objet
1348    *
1349    * @retval boolean True si l'utilisateur a accès, false sinon
1350    */    
1351   function canCreate($LSobject) {
1352     return $this -> canAccess($LSobject,NULL,'w','rdn');
1353   }
1354   
1355   /**
1356    * Retourne le droit de l'utilisateur Ã  gérer la relation d'objet
1357    * 
1358    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1359    * @param[in] string $LSobject Le type de l'objet
1360    * @param[in] string $relationName Le nom de la relation avec l'objet
1361    * @param[in] string $right Le type de droit a vérifier ('r' ou 'w')
1362    *
1363    * @retval boolean True si l'utilisateur a accès, false sinon
1364    */
1365   function relationCanAccess($dn,$LSobject,$relationName,$right=NULL) {
1366     if (!isset($GLOBALS['LSobjects'][$LSobject]['relations'][$relationName]))
1367       return;
1368     $whoami = $this -> whoami($dn);
1369
1370     if (($right=='w') || ($right=='r')) {
1371       $r = 'n';
1372       foreach($whoami as $who) {
1373         $nr = $GLOBALS['LSobjects'][$LSobject]['relations'][$relationName]['rights'][$who];
1374         if($nr == 'w') {
1375           $r = 'w';
1376         }
1377         else if($nr == 'r') {
1378           if ($r=='n') {
1379             $r='r';
1380           }
1381         }
1382       }
1383       
1384       if ($r == $right) {
1385         return true;
1386       }
1387     }
1388     else {
1389       foreach($whoami as $who) {
1390         if (($GLOBALS['LSobjects'][$LSobject]['relations'][$relationName]['rights'][$who] == 'w') || ($GLOBALS['LSobjects'][$LSobject]['relations'][$relationName]['rights'][$who] == 'r')) {
1391           return true;
1392         }
1393       }
1394     }
1395     return;
1396   }
1397
1398   /**
1399    * Retourne le droit de l'utilisateur Ã  modifier la relation d'objet
1400    * 
1401    * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1402    * @param[in] string $LSobject Le type de l'objet
1403    * @param[in] string $relationName Le nom de la relation avec l'objet
1404    *
1405    * @retval boolean True si l'utilisateur a accès, false sinon
1406    */  
1407   function relationCanEdit($dn,$LSobject,$relationName) {
1408     return $this -> relationCanAccess($dn,$LSobject,$relationName,'w');
1409   }
1410
1411   /**
1412    * Ajoute un fichier temporaire
1413    * 
1414    * @author Benjamin Renard <brenard@easter-eggs.com>
1415    * 
1416    * @retval void
1417    **/
1418   function addTmpFile($value,$filePath) {
1419     $hash = mhash(MHASH_MD5,$value);
1420     $this -> tmp_file[$filePath] = $hash;
1421     $_SESSION['LSsession']['tmp_file'][$filePath] = $hash;
1422   }
1423   
1424   /**
1425    * Retourne le chemin du fichier temporaire si l'existe
1426    * 
1427    * @author Benjamin Renard <brenard@easter-eggs.com>
1428    * 
1429    * @param[in] $value La valeur du fichier
1430    * 
1431    * @retval mixed 
1432    **/
1433   function tmpFileExist($value) {
1434     $hash = mhash(MHASH_MD5,$value);
1435     foreach($this -> tmp_file as $filePath => $contentHash) {
1436       if ($hash == $contentHash) {
1437         return $filePath;
1438       }
1439     }
1440     return false;
1441   }
1442   
1443   /**
1444    * Retourne le chemin du fichier temporaire
1445    * 
1446    * Retourne le chemin du fichier temporaire qu'il créera Ã  partir de la valeur
1447    * s'il n'existe pas déjà.
1448    * 
1449    * @author Benjamin Renard <brenard@easter-eggs.com>
1450    * 
1451    * @param[in] $value La valeur du fichier
1452    * 
1453    * @retval mixed 
1454    **/
1455   function getTmpFile($value) {
1456     $exist = $this -> tmpFileExist($value);
1457     if (!$exist) {
1458       $img_path = LS_TMP_DIR .rand().'.tmp';
1459       $fp = fopen($img_path, "w");
1460       fwrite($fp, $value);
1461       fclose($fp);
1462       $this -> addTmpFile($value,$img_path);
1463       return $img_path;
1464     }
1465     else {
1466       return $exist;
1467     }
1468   }
1469   
1470   /**
1471    * Supprime les fichiers temporaires
1472    * 
1473    * @author Benjamin Renard <brenard@easter-eggs.com>
1474    * 
1475    * @retval void
1476    **/
1477   function deleteTmpFile($filePath=NULL) {
1478     if ($filePath) {
1479         @unlink($filePath);
1480         unset($this -> tmp_file[$filePath]);
1481         unset($_SESSION['LSsession']['tmp_file'][$filePath]);
1482     }
1483     else {
1484       foreach($this -> tmp_file as $file => $content) {
1485         @unlink($file);
1486       }
1487       $this -> tmp_file = array();
1488       $_SESSION['LSsession']['tmp_file'] = array();
1489     }
1490   }
1491
1492   /**
1493    * Retourne true si le cache des droits est activé
1494    *
1495    * @author Benjamin Renard <brenard@easter-eggs.com>
1496    * 
1497    * @retval boolean True si le cache des droits est activé, false sinon.
1498    */
1499   function cacheLSprofiles() {
1500     return ( ($GLOBALS['LSconfig']['cacheLSprofiles']) || ($this -> ldapServer['cacheLSprofiles']) );
1501   }
1502
1503   /**
1504    * Retourne true si le cache des subDn est activé
1505    *
1506    * @author Benjamin Renard <brenard@easter-eggs.com>
1507    * 
1508    * @retval boolean True si le cache des subDn est activé, false sinon.
1509    */
1510   function cacheSudDn() {
1511     return (($GLOBALS['LSconfig']['cacheSubDn']) || ($this -> ldapServer['cacheSubDn']));
1512   }
1513   
1514   /**
1515    * Retourne true si le cache des recherches est activé
1516    *
1517    * @author Benjamin Renard <brenard@easter-eggs.com>
1518    * 
1519    * @retval boolean True si le cache des recherches est activé, false sinon.
1520    */
1521   function cacheSearch() {
1522     return (($GLOBALS['LSconfig']['cacheSearch']) || ($this -> ldapServer['cacheSearch']));
1523   }
1524   
1525   /**
1526    * Retourne le label des niveaux pour le serveur ldap courant
1527    * 
1528    * @author Benjamin Renard <brenard@easter-eggs.com>
1529    * 
1530    * @retval string Le label des niveaux pour le serveur ldap dourant
1531    */
1532   function getSubDnLabel() {
1533     return ($this -> ldapServer['subDnLabel']!='')?$this -> ldapServer['subDnLabel']:_('Niveau');
1534   }
1535   
1536   /**
1537    * Retourne le nom du subDn
1538    * 
1539    * @param[in] $subDn string subDn
1540    * 
1541    * @retval string Le nom du subDn ou '' sinon
1542    */
1543   function getSubDnName($subDn=false) {
1544     if (!$subDn) {
1545       $subDn = $this -> topDn;
1546     }
1547     if ($this -> getSubDnLdapServer()) {
1548       if (isset($this -> _subDnLdapServer[$this -> ldapServerId][$subDn])) {
1549         return $this -> _subDnLdapServer[$this -> ldapServerId][$subDn];
1550       }
1551     }
1552     return '';
1553   }
1554
1555   /**
1556    * L'objet est t-il utilisé pour listé les subDnS
1557    * 
1558    * @param[in] $type string Le type d'objet
1559    * 
1560    * @retval boolean true si le type d'objet est un subDnObject, false sinon
1561    */
1562   function isSubDnLSobject($type) {
1563     $result = false;
1564     if (is_array($this -> ldapServer['subDn']['LSobject'])) {
1565       foreach($this -> ldapServer['subDn']['LSobject'] as $key => $value) {
1566         if ($key==$type) {
1567           $result=true;
1568         }
1569       }
1570     }
1571     return $result;
1572   }
1573   
1574   /**
1575    * Indique si un type d'objet est dans le menu courant
1576    * 
1577    * @retval boolean true si le type d'objet est dans le menu, false sinon
1578    */
1579   function in_menu($LSobject,$topDn=NULL) {
1580     if (!$topDn) {
1581       $topDn=$this -> topDn;
1582     }
1583     return isset($this -> LSaccess[$topDn][$LSobject]);
1584   }
1585   
1586   /**
1587    * Indique si le serveur LDAP courant a des subDn
1588    * 
1589    * @retval boolean true si le serveur LDAP courant a des subDn, false sinon
1590    */
1591   function haveSubDn() {
1592     return (is_array($this -> ldapServer['subDn']));
1593   }
1594
1595   /**
1596    * Ajoute une information à afficher
1597    * 
1598    * @param[in] $msg string Le message à afficher
1599    * 
1600    * @retval void
1601    */
1602   function addInfo($msg) {
1603     $_SESSION['LSsession_infos'][]=$msg;
1604   }
1605   
1606   /**
1607    * Redirection de l'utilisateur vers une autre URL
1608    * 
1609    * @param[in] $url string L'URL
1610    * @param[in] $exit boolean Si true, l'execution script s'arrête après la redirection
1611    * 
1612    * @retval void
1613    */  
1614   function redirect($url,$exit=true) {
1615     $GLOBALS['Smarty'] -> assign('url',$url);
1616     $GLOBALS['Smarty'] -> display('redirect.tpl');
1617     if ($exit) {
1618       exit();
1619     }
1620   }
1621   
1622   /**
1623    * Retourne l'adresse mail d'emission configurée pour le serveur courant
1624    * 
1625    * @retval string Adresse mail d'emission
1626    */
1627   function getEmailSender() {
1628     return $this -> ldapServer['emailSender'];  
1629   }
1630   
1631   /**
1632    * Ajout d'une information d'aide
1633    * 
1634    * @param[in] $group string Le nom du groupe d'infos dans lequels ajouter
1635    *                          celle-ci
1636    * @param[in] $infos array  Tableau array(name => value) des infos
1637    * 
1638    * @retval void
1639    */
1640   function addHelpInfos($group,$infos) {
1641     if (is_array($infos)) {
1642       if (is_array($this -> _JSconfigParams['helpInfos'][$group])) {
1643         $this -> _JSconfigParams['helpInfos'][$group] = array_merge($this -> _JSconfigParams['helpInfos'][$group],$infos);
1644       }
1645       else {
1646         $this -> _JSconfigParams['helpInfos'][$group] = $infos;
1647       }
1648     }
1649   }
1650 }
1651
1652 /*
1653  * Error Codes
1654  */
1655 $GLOBALS['LSerror_code']['LSsession_01'] = array (
1656   'msg' => _("LSsession : The constant %{const} is not defined.")
1657 );
1658 $GLOBALS['LSerror_code']['LSsession_02'] = array (
1659   'msg' => _("LSsession : The %{addon} support is uncertain. Verify system compatibility and the add-on configuration.")
1660 );
1661 $GLOBALS['LSerror_code']['LSsession_03'] = array (
1662   'msg' => _("LSsession : LDAP server's configuration data are invalid. Impossible d'établir une connexion.")
1663 );
1664 $GLOBALS['LSerror_code']['LSsession_04'] = array (
1665   'msg' => _("LSsession : Failed to load LSobject type %{type} : unknon type.")
1666 );
1667 // no longer used
1668 /*$GLOBALS['LSerror_code'][1005] = array (
1669   'msg' => _("LSsession : Object type use for authentication is unknow (%{type}).")
1670 );*/
1671 $GLOBALS['LSerror_code']['LSsession_06'] = array (
1672   'msg' => _("LSsession : Login or password incorrect.")
1673 );
1674 $GLOBALS['LSerror_code']['LSsession_07'] = array (
1675   'msg' => _("LSsession : Impossible to identify you : Duplication of identities.")
1676 );
1677 $GLOBALS['LSerror_code']['LSsession_08'] = array (
1678   'msg' => _("LSsession : Can't load Smarty template engine.")
1679 );
1680 $GLOBALS['LSerror_code']['LSsession_09'] = array (
1681   'msg' => _("LSsession : Can't connect to LDAP server.")
1682 );
1683 $GLOBALS['LSerror_code']['LSsession_10'] = array (
1684   'msg' => _("LSsession : Impossible to load authentification objects's class.")
1685 );
1686 $GLOBALS['LSerror_code']['LSsession_11'] = array (
1687   'msg' => _("LSsession : Your are not authorized to do this action.")
1688 );
1689 $GLOBALS['LSerror_code']['LSsession_12'] = array (
1690   'msg' => _("LSsession : Some informations are missing to display this page.")
1691 );
1692 // 13 -> 16 : not yet used
1693 $GLOBALS['LSerror_code']['LSsession_17'] = array (
1694   'msg' => _("LSsession : Error during creation of list of levels. Contact administrators. (Code : %{code})")
1695 );
1696 $GLOBALS['LSerror_code']['LSsession_18'] = array (
1697   'msg' => _("LSsession : The password recovery is disabled for this LDAP server.")
1698 );
1699 $GLOBALS['LSerror_code']['LSsession_19'] = array (
1700   'msg' => _("LSsession : Some informations are missing to recover your password. Contact administrators.")
1701 );
1702 $GLOBALS['LSerror_code']['LSsession_20'] = array (
1703   'msg' => _("LSsession : Error during password recovery. Contact administrators.(Step : %{step})")
1704 );
1705 // 21 : not yet used
1706 $GLOBALS['LSerror_code']['LSsession_22'] = array(
1707   'msg' => _("LSsession : problem during initialisation.")
1708 );
1709
1710
1711 // LSrelations
1712 $GLOBALS['LSerror_code']['LSrelations_01'] = array (
1713   'msg' => _("LSrelations : The listing function for the relation %{relation} is unknow.")
1714 );
1715 $GLOBALS['LSerror_code']['LSrelations_02'] = array (
1716   'msg' => _("LSrelations : The update function of the relation %{relation} is unknow.")
1717 );
1718 $GLOBALS['LSerror_code']['LSrelations_03'] = array (
1719   'msg' => _("LSrelations : Error during relation update of the relation %{relation}.")
1720 );
1721 $GLOBALS['LSerror_code']['LSrelations_04'] = array (
1722   'msg' => _("LSrelations : Object type %{LSobject} unknow (Relation : %{relation}).")
1723 );
1724 $GLOBALS['LSerror_code']['LSrelations_05'] = array (
1725   'msg' => _("LSrelation : Some parameters are missing in the invocation of the methods of handling relations standard (Methode : %{meth}).")
1726 );
1727 ?>