2 /*******************************************************************************
3 * Copyright (C) 2007 Easter-eggs
4 * http://ldapsaisie.labs.libre-entreprise.org
6 * Author: See AUTHORS file in top-level directory.
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.
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.
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.
21 ******************************************************************************/
24 * Gestion des sessions
26 * Cette classe gère les sessions d'utilisateurs.
28 * @author Benjamin Renard <brenard@easter-eggs.com>
32 // La configuration du serveur Ldap utilisé
33 public static $ldapServer = NULL;
35 // L'id du serveur Ldap utilisé
36 private static $ldapServerId = NULL;
39 private static $topDn = NULL;
41 // Le DN de l'utilisateur connecté
42 private static $dn = NULL;
44 // Le RDN de l'utilisateur connecté (son identifiant)
45 private static $rdn = NULL;
47 // Les LSprofiles de l'utilisateur
48 private static $LSprofiles = array();
50 // Les droits d'accès de l'utilisateur
51 private static $LSaccess = array();
53 // Authentification parameters
54 private static $authParams = array();
56 // Les fichiers temporaires
57 private static $tmp_file = array();
59 // Langue et encodage actuel
60 private static $lang = NULL;
61 private static $encoding = NULL;
64 * Constante de classe non stockée en session
66 // Le template à afficher
67 private static $template = NULL;
69 // Les subDn des serveurs Ldap
70 private static $_subDnLdapServer = array();
73 private static $ajaxDisplay = false;
75 // Les fichiers JS à charger dans la page
76 private static $JSscripts = array();
78 // Les paramètres JS à communiquer dans la page
79 private static $_JSconfigParams = array();
81 // Les fichiers CSS à charger dans la page
82 private static $CssFiles = array();
84 // L'objet de l'utilisateur connecté
85 private static $LSuserObject = NULL;
87 // The LSauht object of the session
88 private static $LSauthObject = false;
91 * Include un fichier PHP
93 * @author Benjamin Renard <brenard@easter-eggs.com>
95 * @retval true si tout c'est bien passé, false sinon
97 public static function includeFile($file) {
98 if (!file_exists($file)) {
102 return include_once($file);
105 return @include_once($file);
111 * Lancement de LSconfig
113 * @author Benjamin Renard <brenard@easter-eggs.com>
115 * @retval true si tout c'est bien passé, false sinon
117 private static function startLSconfig() {
118 if (self :: loadLSclass('LSconfig')) {
119 if (LSconfig :: start()) {
123 die("ERROR : Can't load configuration files.");
128 * Lancement et initialisation de Smarty
130 * @author Benjamin Renard <brenard@easter-eggs.com>
132 * @retval true si tout c'est bien passé, false sinon
134 private static function startLStemplate() {
135 if ( self :: includeFile(LSconfig :: get('Smarty')) ) {
136 $GLOBALS['Smarty'] = new Smarty();
137 $GLOBALS['Smarty'] -> template_dir = LS_TEMPLATES_DIR;
138 $GLOBALS['Smarty'] -> compile_dir = LS_TMP_DIR;
141 $GLOBALS['Smarty'] -> caching = 0;
142 // cache files are always regenerated
143 $GLOBALS['Smarty'] -> force_compile = TRUE;
144 // recompile template if it is changed
145 $GLOBALS['Smarty'] -> compile_check = TRUE;
146 if (isset($_REQUEST['debug_smarty'])) {
148 $GLOBALS['Smarty'] -> debugging = true;
152 $GLOBALS['Smarty'] -> assign('LS_CSS_DIR',LS_CSS_DIR);
153 $GLOBALS['Smarty'] -> assign('LS_IMAGES_DIR',LS_IMAGES_DIR);
155 self :: addJSconfigParam('LS_IMAGES_DIR',LS_IMAGES_DIR);
158 die("ERROR : Can't load Smarty.");
163 * Retourne le topDn de la session
165 * @author Benjamin Renard <brenard@easter-eggs.com>
167 * @retval string le topDn de la session
169 public static function getTopDn() {
170 if (!is_null(self :: $topDn)) {
171 return self :: $topDn;
174 return self :: getRootDn();
179 * Retourne le rootDn de la session
181 * @author Benjamin Renard <brenard@easter-eggs.com>
183 * @retval string le rootDn de la session
185 public static function getRootDn() {
186 return self :: $ldapServer['ldap_config']['basedn'];
190 * Initialisation de la gestion des erreurs
192 * Création de l'objet LSerror
194 * @author Benjamin Renard <brenard@easter-eggs.com
196 * @retval boolean true si l'initialisation a réussi, false sinon.
198 private static function startLSerror() {
199 if(!self :: loadLSclass('LSerror')) {
202 self :: defineLSerrors();
207 * Chargement d'une classe d'LdapSaisie
209 * @param[in] $class Nom de la classe à charger (Exemple : LSpeople)
210 * @param[in] $type (Optionnel) Type de classe à charger (Exemple : LSobjects)
212 * @author Benjamin Renard <brenard@easter-eggs.com
214 * @retval boolean true si le chargement a réussi, false sinon.
216 public static function loadLSclass($class,$type='') {
217 if (class_exists($class))
221 return self :: includeFile(LS_CLASS_DIR .'class.'.$type.$class.'.php');
225 * Chargement d'un object LdapSaisie
227 * @param[in] $object Nom de l'objet à charger
229 * @retval boolean true si le chargement a réussi, false sinon.
231 public static function loadLSobject($object) {
232 if(class_exists($object)) {
236 self :: loadLSclass('LSldapObject');
237 if (!self :: loadLSclass($object,'LSobjects')) {
240 if (!self :: includeFile( LS_OBJECTS_DIR . 'config.LSobjects.'.$object.'.php' )) {
244 if (!LSconfig :: set("LSobjects.$object",$GLOBALS['LSobjects'][$object])) {
247 else if (isset($GLOBALS['LSobjects'][$object]['LSaddons'])){
248 if (is_array($GLOBALS['LSobjects'][$object]['LSaddons'])) {
249 foreach ($GLOBALS['LSobjects'][$object]['LSaddons'] as $addon) {
250 if (!self :: loadLSaddon($addon)) {
256 if (!self :: loadLSaddon($GLOBALS['LSobjects'][$object]['LSaddons'])) {
263 LSerror :: addErrorCode('LSsession_04',$object);
270 * Chargement d'un addons d'LdapSaisie
272 * @param[in] $addon Nom de l'addon à charger (Exemple : samba)
274 * @author Benjamin Renard <brenard@easter-eggs.com
276 * @retval boolean true si le chargement a réussi, false sinon.
278 public static function loadLSaddon($addon) {
279 if(self :: includeFile(LS_ADDONS_DIR .'LSaddons.'.$addon.'.php')) {
280 self :: includeFile(LS_CONF_DIR."LSaddons/config.LSaddons.".$addon.".php");
281 if (!call_user_func('LSaddon_'. $addon .'_support')) {
282 LSerror :: addErrorCode('LSsession_02',$addon);
291 * Chargement d'une classe d'authentification d'LdapSaisie
293 * @param[in] $auth Nom de la classe d'authentification a charger (Exemple : HTTP)
295 * @author Benjamin Renard <brenard@easter-eggs.com
297 * @retval boolean true si le chargement a reussi, false sinon.
299 public static function loadLSauth($auth=false) {
300 if (self :: loadLSclass('LSauth')) {
302 if(self :: includeFile(LS_CLASS_DIR .'class.LSauth'.$auth.'.php')) {
303 self :: includeFile(LS_CONF_DIR."LSauth/config.LSauth".$auth.".php");
312 LSerror :: addErrorCode('LSsession_05','LSauth');
318 * Chargement des addons LdapSaisie
320 * Chargement des LSaddons contenue dans la variable
321 * $GLOBALS['LSaddons']['loads']
323 * @retval boolean true si le chargement a réussi, false sinon.
325 public static function loadLSaddons() {
326 $conf=LSconfig :: get('LSaddons.loads');
327 if(!is_array($conf)) {
328 LSerror :: addErrorCode('LSsession_01',"LSaddons['loads']");
332 foreach ($conf as $addon) {
333 self :: loadLSaddon($addon);
343 public static function setLocale() {
344 if (isset($_REQUEST['lang'])) {
345 $lang = $_REQUEST['lang'];
347 elseif (isset($_SESSION['LSlang'])) {
348 $lang = $_SESSION['LSlang'];
350 elseif (isset(self :: $ldapServer['lang'])) {
351 $lang = self :: $ldapServer['lang'];
354 $lang = LSconfig :: get('lang');
357 if (isset($_REQUEST['encoding'])) {
358 $encoding = $_REQUEST['encoding'];
360 elseif (isset($_SESSION['LSencoding'])) {
361 $encoding = $_SESSION['LSencoding'];
363 elseif (isset(self :: $ldapServer['encoding'])) {
364 $encoding = self :: $ldapServer['encoding'];
367 $encoding = LSconfig :: get('encoding');
370 $_SESSION['LSlang']=$lang;
372 $_SESSION['LSencoding']=$encoding;
373 self :: $encoding=$encoding;
376 if (self :: localeExist($lang,$encoding)) {
378 $lang.='.'.$encoding;
380 setlocale(LC_ALL, $lang);
381 bindtextdomain(LS_TEXT_DOMAIN, LS_I18N_DIR);
382 textdomain(LS_TEXT_DOMAIN);
384 if (is_file(LS_I18N_DIR.'/'.$lang.'/lang.php')) {
385 include(LS_I18N_DIR.'/'.$lang.'/lang.php');
389 if ($encoding && $lang) {
390 $lang.='.'.$encoding;
392 LSdebug('La locale "'.$lang.'" n\'existe pas, utilisation de la locale par défaut.');
397 * Retourne la liste des langues disponibles
399 * @retval array Tableau/Liste des langues disponibles
401 public static function getLangList() {
402 $list=array('en_US');
403 if (self :: $encoding) {
404 $regex = '^([a-zA-Z_]*)\.'.self :: $encoding.'$';
407 $regex = '^([a-zA-Z_]*)$';
409 if ($handle = opendir(LS_I18N_DIR)) {
410 while (false !== ($file = readdir($handle))) {
411 if(is_dir(LS_I18N_DIR.'/'.$file)) {
412 if (ereg($regex,$file,$regs)) {
413 if (!in_array($regs[1],$list)) {
424 * Retourne la langue courante de la session
426 * @param[in] boolean Si true, le code langue retourné sera court
428 * @retval string La langue de la session
430 public static function getLang($short=false) {
432 return strtolower(self :: $lang[0].self :: $lang[1]);
434 return self :: $lang;
438 * Vérifie si une locale est disponible
440 * @param[in] $lang string La langue (Ex : fr_FR)
441 * @param[in] $encoding string L'encodage de caractère (Ex : UTF8)
443 * @retval boolean True si la locale est disponible, False sinon
445 public static function localeExist($lang,$encoding) {
446 if ( !$lang && !$encoding ) {
449 $locale=$lang.(($encoding)?'.'.$encoding:'');
450 if ($locale=='en_US.UTF8') {
453 return (is_dir(LS_I18N_DIR.'/'.$locale));
457 * Initialisation LdapSaisie
459 * @retval boolean True si l'initialisation à réussi, false sinon.
461 public static function initialize() {
462 if (!self :: startLSconfig()) {
466 self :: startLStemplate();
472 self :: startLSerror();
473 self :: loadLSaddons();
478 * Initialisation de la session LdapSaisie
480 * Initialisation d'une LSsession :
481 * - Authentification et activation du mécanisme de session de LdapSaisie
482 * - ou Chargement des paramètres de la session à partir de la variable
483 * $_SESSION['LSsession'].
484 * - ou Destruction de la session en cas de $_GET['LSsession_logout'].
486 * @retval boolean True si l'initialisation à réussi (utilisateur authentifié), false sinon.
488 public static function startLSsession() {
489 if (!self :: initialize()) {
493 if(isset($_SESSION['LSsession']['dn']) && !isset($_GET['LSsession_recoverPassword'])) {
495 self :: $topDn = $_SESSION['LSsession']['topDn'];
496 self :: $dn = $_SESSION['LSsession']['dn'];
497 self :: $rdn = $_SESSION['LSsession']['rdn'];
498 self :: $ldapServerId = $_SESSION['LSsession']['ldapServerId'];
499 self :: $tmp_file = $_SESSION['LSsession']['tmp_file'];
500 self :: $authParams = $_SESSION['LSsession']['authParams'];
502 if (isset($_GET['LSsession_logout'])) {
503 $authObj = self :: getLSauthObject();
505 $authObj -> logout();
509 if (is_array($_SESSION['LSsession']['tmp_file'])) {
510 self :: $tmp_file = $_SESSION['LSsession']['tmp_file'];
512 self :: deleteTmpFile();
513 unset($_SESSION['LSsession']);
515 self :: redirect('index.php');
519 if ( self :: cacheLSprofiles() && !isset($_REQUEST['LSsession_refresh']) ) {
520 self :: setLdapServer(self :: $ldapServerId);
521 self :: $LSprofiles = $_SESSION['LSsession']['LSprofiles'];
522 self :: $LSaccess = $_SESSION['LSsession']['LSaccess'];
523 if (!self :: LSldapConnect())
527 self :: setLdapServer(self :: $ldapServerId);
528 if (!self :: LSldapConnect())
530 self :: loadLSprofiles();
533 if ( self :: cacheSudDn() && (!isset($_REQUEST['LSsession_refresh'])) ) {
534 self :: $_subDnLdapServer = $_SESSION['LSsession_subDnLdapServer'];
537 if (!self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
541 self :: getLSuserObject();
543 if ( !self :: cacheLSprofiles() || isset($_REQUEST['LSsession_refresh']) ) {
544 self :: loadLSaccess();
547 $GLOBALS['Smarty'] -> assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
549 if ($_POST['LSsession_topDn']) {
550 if (self :: validSubDnLdapServer($_POST['LSsession_topDn'])) {
551 self :: $topDn = $_POST['LSsession_topDn'];
552 $_SESSION['LSsession']['topDn'] = $_POST['LSsession_topDn'];
560 if (isset($_GET['LSsession_recoverPassword'])) {
563 // Session inexistante
564 if (isset($_POST['LSsession_ldapserver'])) {
565 self :: setLdapServer($_POST['LSsession_ldapserver']);
568 self :: setLdapServer(0);
571 // Connexion au serveur LDAP
572 if (self :: LSldapConnect()) {
575 if ( $_POST['LSsession_topDn'] != '' ){
576 self :: $topDn = $_POST['LSsession_topDn'];
579 self :: $topDn = self :: $ldapServer['ldap_config']['basedn'];
581 $_SESSION['LSsession_topDn']=self :: $topDn;
583 if (isset($_GET['LSsession_recoverPassword'])) {
584 $recoveryPasswordInfos = self :: recoverPasswd(
585 $_REQUEST['LSsession_user'],
586 $_GET['recoveryHash']
590 $authObj=self :: getLSauthObject();
592 if ($authObj -> getPostData()) {
593 $LSuserObject = $authObj -> authenticate();
595 // Authentication successful
596 self :: $LSuserObject = $LSuserObject;
597 self :: $dn = $LSuserObject->getValue('dn');
598 self :: $rdn = $LSuserObject->getValue('rdn');
599 self :: loadLSprofiles();
600 self :: loadLSaccess();
601 $GLOBALS['Smarty'] -> assign('LSsession_username',self :: getLSuserObject() -> getDisplayName());
602 $_SESSION['LSsession']=self :: getContextInfos();
610 LSerror :: addErrorCode('LSsession_09');
613 if (self :: $ldapServerId) {
614 $GLOBALS['Smarty'] -> assign('ldapServerId',self :: $ldapServerId);
616 $GLOBALS['Smarty'] -> assign('topDn',self :: $topDn);
617 if (isset($_GET['LSsession_recoverPassword'])) {
618 self :: displayRecoverPasswordForm($recoveryPasswordInfos);
620 elseif(self :: $authParams['displayLoginForm']) {
621 self :: displayLoginForm();
624 self :: setTemplate('blank.tpl');
625 LSerror :: addErrorCode('LSsession_10');
634 * @retval LSauth object or false
636 private static function getLSauthObject() {
637 if (!self :: $LSauthObject) {
638 if (self :: loadLSauth()) {
639 if (isset(self :: $ldapServer['LSauth']['method'])) {
640 $LSauthClass = 'LSauth'.self :: $ldapServer['LSauth']['method'];
641 if (!self :: loadLSauth(self :: $ldapServer['LSauth']['method'])) {
642 LSerror :: addErrorCode('LSsession_08',self :: $ldapServer['LSauth']['method']);
643 $LSauthClass = 'LSauth';
647 $LSauthClass = 'LSauth';
650 self :: $LSauthObject = new $LSauthClass();
651 self :: $authParams = self :: $LSauthObject->params;
654 return self :: $LSauthObject;
658 * Do recover password
660 * @param[in] $username string The submited username
661 * @param[in] $recoveryHash string The submited recoveryHash
663 * @retval array The recoveryPassword infos for template
665 private static function recoverPasswd($username,$recoveryHash) {
666 $recoveryPasswordInfos=array();
667 if ( self :: loadLSobject(self :: $ldapServer['authObjectType']) ) {
668 $authobject = new self :: $ldapServer['authObjectType']();
669 if (!empty($recoveryHash)) {
670 $filter=Net_LDAP2_Filter::create(
671 self :: $ldapServer['recoverPassword']['recoveryHashAttr'],
675 $result = $authobject -> listObjects($filter,self :: $topDn);
677 elseif (!empty($username)) {
678 $result = $authobject -> searchObject(
681 self :: $ldapServer['authObjectFilter']
685 return $recoveryPasswordInfos;
688 $nbresult=count($result);
691 LSdebug('hash/username incorrect');
692 LSerror :: addErrorCode('LSsession_06');
694 elseif ($nbresult>1) {
695 LSerror :: addErrorCode('LSsession_07');
698 $rdn = $result[0] -> getValue('rdn');
700 LSdebug('Recover : Id trouvé : '.$username);
701 if (self :: $ldapServer['recoverPassword']) {
702 if (self :: loadLSaddon('mail')) {
703 LSdebug('Récupération active');
705 $emailAddress = $user -> getValue(self :: $ldapServer['recoverPassword']['mailAttr']);
706 $emailAddress = $emailAddress[0];
708 if (checkEmail($emailAddress)) {
709 LSdebug('Email : '.$emailAddress);
710 self :: $dn = $user -> getDn();
712 // 1ère étape : envoie du recoveryHash
713 if (empty($recoveryHash)) {
714 $hash=self :: recoverPasswdFirstStep($user);
716 if (self :: recoverPasswdSendMail($emailAddress,1,$hash)) {
717 // Mail a bien été envoyé
718 $recoveryPasswordInfos['recoveryHashMail']=$emailAddress;
722 // 2nd étape : génération du mot de passe + envoie par mail
724 $pwd=self :: recoverPasswdSecondStep($user);
726 if (self :: recoverPasswdSendMail($emailAddress,2,$pwd)){
727 // Mail a bien été envoyé
728 $recoveryPasswordInfos['newPasswordMail']=$emailAddress;
734 LSerror :: addErrorCode('LSsession_19');
739 LSerror :: addErrorCode('LSsession_18');
743 return $recoveryPasswordInfos;
747 * Send recover password mail
749 * @param[in] $mail string The user's mail
750 * @param[in] $step integer The step
751 * @param[in] $info string The info for formatted message
753 * @retval boolean True on success or False
755 private static function recoverPasswdSendMail($mail,$step,$info) {
758 if (self :: $ldapServer['recoverPassword']['recoveryEmailSender']) {
759 $sendParams['From']=self :: $ldapServer['recoverPassword']['recoveryEmailSender'];
763 if ($_SERVER['HTTPS']=='on') {
764 $recovery_url='https://';
767 $recovery_url='http://';
769 $recovery_url .= $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'&recoveryHash='.$info;
771 $subject = self :: $ldapServer['recoverPassword']['recoveryHashMail']['subject'];
773 self :: $ldapServer['recoverPassword']['recoveryHashMail']['msg'],
778 $subject = self :: $ldapServer['recoverPassword']['newPasswordMail']['subject'];
780 self :: $ldapServer['recoverPassword']['newPasswordMail']['msg'],
785 if (!sendMail($mail,$subject,$msg,$sendParams)) {
786 LSdebug("Problème durant l'envoie du mail");
787 LSerror :: addErrorCode('LSsession_20',4);
795 * Do first step of recovering password
797 * @param[in] $user LSldapObject The LSldapObject of the user
799 * @retval string|False The recory hash on success or False
801 private static function recoverPasswdFirstStep($user) {
803 $rdn=$user -> getValue('rdn');
805 $recovery_hash = md5($rdn . strval(time()) . strval(rand()));
807 $lostPasswdForm = $user -> getForm('lostPassword');
808 $lostPasswdForm -> setPostData(
810 self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => $recovery_hash
815 if($lostPasswdForm -> validate()) {
816 if ($user -> updateData('lostPassword')) {
817 // recoveryHash de l'utilisateur mis à jour
818 return $recovery_hash;
821 // Erreur durant la mise à jour de l'objet
822 LSdebug("Erreur durant la mise à jour de l'objet");
823 LSerror :: addErrorCode('LSsession_20',6);
827 // Erreur durant la validation du formulaire de modification de perte de password
828 LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
829 LSerror :: addErrorCode('LSsession_20',5);
835 * Do second step of recovering password
837 * @param[in] $user LSldapObject The LSldapObject of the user
839 * @retval string|False The new password on success or False
841 private static function recoverPasswdSecondStep($user) {
842 $attr=$user -> attrs[self :: $ldapServer['authObjectTypeAttrPwd']];
843 if ($attr instanceof LSattribute) {
844 $mdp = generatePassword(
845 $attr -> config['html_options']['chars'],
846 $attr -> config['html_options']['lenght']
848 LSdebug('Nvx mpd : '.$mdp);
849 $lostPasswdForm = $user -> getForm('lostPassword');
850 $lostPasswdForm -> setPostData(
852 self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => array(''),
853 self :: $ldapServer['authObjectTypeAttrPwd'] => array($mdp)
857 if($lostPasswdForm -> validate()) {
858 if ($user -> updateData('lostPassword')) {
862 // Erreur durant la mise à jour de l'objet
863 LSdebug("Erreur durant la mise à jour de l'objet");
864 LSerror :: addErrorCode('LSsession_20',3);
868 // Erreur durant la validation du formulaire de modification de perte de password
869 LSdebug("Erreur durant la validation du formulaire de modification de perte de password");
870 LSerror :: addErrorCode('LSsession_20',2);
874 // l'attribut password n'existe pas
875 LSdebug("L'attribut password n'existe pas");
876 LSerror :: addErrorCode('LSsession_20',1);
882 * Retourne les informations du contexte
884 * @author Benjamin Renard <brenard@easter-eggs.com
886 * @retval array Tableau associatif des informations du contexte
888 private static function getContextInfos() {
890 'tmp_file' => self :: $tmp_file,
891 'topDn' => self :: $topDn,
893 'rdn' => self :: $rdn,
894 'ldapServerId' => self :: $ldapServerId,
895 'ldapServer' => self :: $ldapServer,
896 'LSprofiles' => self :: $LSprofiles,
897 'LSaccess' => self :: $LSaccess,
898 'authParams' => self :: $authParams
903 * Retourne l'objet de l'utilisateur connecté
905 * @author Benjamin Renard <brenard@easter-eggs.com
907 * @retval mixed L'objet de l'utilisateur connecté ou false si il n'a pas put
910 public static function getLSuserObject($dn=null) {
914 if (!self :: $LSuserObject) {
915 if (self :: loadLSobject(self :: $ldapServer['authObjectType'])) {
916 self :: $LSuserObject = new self :: $ldapServer['authObjectType']();
917 self :: $LSuserObject -> loadData(self :: $dn);
923 return self :: $LSuserObject;
927 * Retourne le DN de l'utilisateur connecté
929 * @author Benjamin Renard <brenard@easter-eggs.com
931 * @retval string Le DN de l'utilisateur connecté
933 public static function getLSuserObjectDn() {
938 * Modifie l'utilisateur connecté à la volé
940 * @param[in] $object Mixed L'objet Ldap du nouvel utilisateur
941 * le type doit correspondre à
942 * self :: $ldapServer['authObjectType']
944 * @retval boolean True en cas de succès, false sinon
946 public static function changeAuthUser($object) {
947 if ($object instanceof self :: $ldapServer['authObjectType']) {
948 self :: $dn = $object -> getDn();
949 $rdn = $object -> getValue('rdn');
954 self :: $LSuserObject = $object;
956 if(self :: loadLSprofiles()) {
957 self :: loadLSaccess();
958 $_SESSION['LSsession']=self :: getContextInfos();
966 * Définition du serveur Ldap de la session
968 * Définition du serveur Ldap de la session à partir de son ID dans
969 * le tableau LSconfig :: get('ldap_servers').
971 * @param[in] integer Index du serveur Ldap
973 * @retval boolean True sinon false.
975 public static function setLdapServer($id) {
976 $conf = LSconfig :: get("ldap_servers.$id");
977 if ( is_array($conf) ) {
978 self :: $ldapServerId = $id;
979 self :: $ldapServer = $conf;
989 * Connexion au serveur Ldap
991 * @retval boolean True sinon false.
993 public static function LSldapConnect() {
994 if (self :: $ldapServer) {
995 self :: includeFile(LSconfig :: get('NetLDAP2'));
996 if (!self :: loadLSclass('LSldap')) {
999 LSldap :: connect(self :: $ldapServer['ldap_config']);
1000 if (LSldap :: isConnected()) {
1008 LSerror :: addErrorCode('LSsession_03');
1014 * Use this function to know if subDn is enabled for the curent LdapServer
1018 public static function subDnIsEnabled() {
1019 if (!isset(self :: $ldapServer['subDn'])) {
1022 if ( !is_array(self :: $ldapServer['subDn']) ) {
1029 * Retourne les sous-dns du serveur Ldap courant
1031 * @retval mixed Tableau des subDn, false si une erreur est survenue.
1033 public static function getSubDnLdapServer() {
1034 if (self :: cacheSudDn() && isset(self :: $_subDnLdapServer[self :: $ldapServerId])) {
1035 return self :: $_subDnLdapServer[self :: $ldapServerId];
1037 if (!self::subDnIsEnabled()) {
1041 foreach(self :: $ldapServer['subDn'] as $subDn_name => $subDn_config) {
1042 if ($subDn_name == 'LSobject') {
1043 if (is_array($subDn_config)) {
1044 foreach($subDn_config as $LSobject_name => $LSoject_config) {
1045 if ($LSoject_config['basedn']) {
1046 $basedn = $LSoject_config['basedn'];
1049 $basedn = self::getRootDn();
1051 if ($LSoject_config['displayName']) {
1052 $displayName = $LSoject_config['displayName'];
1055 $displayName = NULL;
1057 if( self :: loadLSobject($LSobject_name) ) {
1058 if ($subdnobject = new $LSobject_name()) {
1059 $tbl_return = $subdnobject -> getSelectArray(NULL,$basedn,$displayName);
1060 if (is_array($tbl_return)) {
1061 $return=array_merge($return,$tbl_return);
1064 LSerror :: addErrorCode('LSsession_17',3);
1068 LSerror :: addErrorCode('LSsession_17',2);
1074 LSerror :: addErrorCode('LSsession_17',1);
1078 if ((isCompatibleDNs($subDn_config['dn'],self :: $ldapServer['ldap_config']['basedn']))&&($subDn_config['dn']!="")) {
1079 $return[$subDn_config['dn']] = __($subDn_name);
1083 if (self :: cacheSudDn()) {
1084 self :: $_subDnLdapServer[self :: $ldapServerId]=$return;
1085 $_SESSION['LSsession_subDnLdapServer'] = self :: $_subDnLdapServer;
1091 * Retourne la liste de subDn du serveur Ldap utilise
1092 * trié par la profondeur dans l'arboressence (ordre décroissant)
1094 * @return array() Tableau des subDn trié
1096 public static function getSortSubDnLdapServer() {
1097 $subDnLdapServer = self :: getSubDnLdapServer();
1098 if (!$subDnLdapServer) {
1101 uksort($subDnLdapServer,"compareDn");
1102 return $subDnLdapServer;
1106 * Retourne les options d'une liste déroulante pour le choix du topDn
1107 * de connexion au serveur Ldap
1109 * Liste les subdn (self :: $ldapServer['subDn'])
1111 * @retval string Les options (<option>) pour la sélection du topDn.
1113 public static function getSubDnLdapServerOptions($selected=NULL) {
1114 $list = self :: getSubDnLdapServer();
1118 foreach($list as $dn => $txt) {
1119 if ($selected && ($selected==$dn)) {
1120 $selected_txt = ' selected';
1125 $display.="<option value=\"".$dn."\"$selected_txt>".$txt."</option>\n";
1133 * Vérifie qu'un subDn est déclaré
1135 * @param[in] string Un subDn
1137 * @retval boolean True si le subDn existe, False sinon
1139 public static function validSubDnLdapServer($subDn) {
1140 $listTopDn = self :: getSubDnLdapServer();
1141 if(is_array($listTopDn)) {
1142 foreach($listTopDn as $dn => $txt) {
1152 * Test un couple LSobject/pwd
1154 * Test un bind sur le serveur avec le dn de l'objet et le mot de passe fourni.
1156 * @param[in] LSobject L'object "user" pour l'authentification
1157 * @param[in] string Le mot de passe à tester
1159 * @retval boolean True si l'authentification à réussi, false sinon.
1161 public static function checkUserPwd($object,$pwd) {
1162 return LSldap :: checkBind($object -> getValue('dn'),$pwd);
1166 * Affiche le formulaire de login
1168 * Défini les informations pour le template Smarty du formulaire de login.
1172 public static function displayLoginForm() {
1173 $GLOBALS['Smarty'] -> assign('pagetitle',_('Connection'));
1174 if (isset($_GET['LSsession_logout'])) {
1175 $GLOBALS['Smarty'] -> assign('loginform_action','index.php');
1178 $GLOBALS['Smarty'] -> assign('loginform_action',$_SERVER['REQUEST_URI']);
1180 if (count(LSconfig :: get('ldap_servers'))==1) {
1181 $GLOBALS['Smarty'] -> assign('loginform_ldapserver_style','style="display: none"');
1183 $GLOBALS['Smarty'] -> assign('loginform_label_ldapserver',_('LDAP server'));
1184 $ldapservers_name=array();
1185 $ldapservers_index=array();
1186 foreach(LSconfig :: get('ldap_servers') as $id => $infos) {
1187 $ldapservers_index[]=$id;
1188 $ldapservers_name[]=__($infos['name']);
1190 $GLOBALS['Smarty'] -> assign('loginform_ldapservers_name',$ldapservers_name);
1191 $GLOBALS['Smarty'] -> assign('loginform_ldapservers_index',$ldapservers_index);
1193 $GLOBALS['Smarty'] -> assign('loginform_label_level',_('Level'));
1194 $GLOBALS['Smarty'] -> assign('loginform_label_user',_('Identifier'));
1195 $GLOBALS['Smarty'] -> assign('loginform_label_pwd',_('Password'));
1196 $GLOBALS['Smarty'] -> assign('loginform_label_submit',_('Connect'));
1197 $GLOBALS['Smarty'] -> assign('loginform_label_recoverPassword',_('Forgot your password ?'));
1199 self :: setTemplate('login.tpl');
1200 self :: addJSscript('LSsession_login.js');
1204 * Affiche le formulaire de récupération de mot de passe
1206 * Défini les informations pour le template Smarty du formulaire de
1207 * récupération de mot de passe
1209 * @param[in] $infos array() Information sur le status du processus de
1210 * recouvrement de mot de passe
1214 public static function displayRecoverPasswordForm($recoveryPasswordInfos) {
1215 $GLOBALS['Smarty'] -> assign('pagetitle',_('Recovery of your credentials'));
1216 $GLOBALS['Smarty'] -> assign('recoverpasswordform_action','index.php?LSsession_recoverPassword');
1218 if (count(LSconfig :: get('ldap_servers'))==1) {
1219 $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapserver_style','style="display: none"');
1222 $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_ldapserver',_('LDAP server'));
1223 $ldapservers_name=array();
1224 $ldapservers_index=array();
1225 foreach(LSconfig :: get('ldap_servers') as $id => $infos) {
1226 $ldapservers_index[]=$id;
1227 $ldapservers_name[]=$infos['name'];
1229 $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapservers_name',$ldapservers_name);
1230 $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapservers_index',$ldapservers_index);
1232 $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_user',_('Identifier'));
1233 $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_submit',_('Validate'));
1234 $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_back',_('Back'));
1236 $recoverpassword_msg = _('Please fill the identifier field to proceed recovery procedure');
1238 if (isset($recoveryPasswordInfos['recoveryHashMail'])) {
1239 $recoverpassword_msg = getFData(
1240 _("An email has been sent to %{mail}. " .
1241 "Please follow the instructions on it."),
1242 $recoveryPasswordInfos['recoveryHashMail']
1246 if (isset($recoveryPasswordInfos['newPasswordMail'])) {
1247 $recoverpassword_msg = getFData(
1248 _("Your new password has been sent to %{mail}. "),
1249 $recoveryPasswordInfos['newPasswordMail']
1253 $GLOBALS['Smarty'] -> assign('recoverpassword_msg',$recoverpassword_msg);
1255 self :: setTemplate('recoverpassword.tpl');
1256 self :: addJSscript('LSsession_recoverPassword.js');
1260 * Défini le template Smarty à utiliser
1262 * Remarque : les fichiers de templates doivent se trouver dans le dossier
1265 * @param[in] string Le nom du fichier de template
1269 public static function setTemplate($template) {
1270 self :: $template = $template;
1274 * Ajoute un script JS au chargement de la page
1276 * Remarque : les scripts doivents être dans le dossier LS_JS_DIR.
1278 * @param[in] $script Le nom du fichier de script à charger.
1282 public static function addJSscript($file,$path=NULL) {
1287 self :: $JSscripts[$path.$file]=$script;
1291 * Ajouter un paramètre de configuration Javascript
1293 * @param[in] $name string Nom de la variable de configuration
1294 * @param[in] $val mixed Valeur de la variable de configuration
1298 public static function addJSconfigParam($name,$val) {
1299 self :: $_JSconfigParams[$name]=$val;
1303 * Ajoute une feuille de style au chargement de la page
1305 * Remarque : les scripts doivents être dans le dossier LS_CSS_DIR.
1307 * @param[in] $script Le nom du fichier css à charger.
1311 public static function addCssFile($file,$path=NULL) {
1316 self :: $CssFiles[$path.$file]=$cssFile;
1320 * Affiche le template Smarty
1322 * Charge les dépendances et affiche le template Smarty
1326 public static function displayTemplate() {
1329 foreach ($GLOBALS['defaultJSscipts'] as $script) {
1330 $JSscript_txt.="<script src='".LS_JS_DIR.$script."' type='text/javascript'></script>\n";
1333 foreach (self :: $JSscripts as $script) {
1334 if (!$script['path']) {
1335 $script['path']=LS_JS_DIR;
1338 $script['path'].='/';
1340 $JSscript_txt.="<script src='".$script['path'].$script['file']."' type='text/javascript'></script>\n";
1343 $KAconf = LSconfig :: get('keepLSsessionActive');
1346 (!isset(self :: $ldapServer['keepLSsessionActive']))
1348 (!($KAconf === false))
1351 (self :: $ldapServer['keepLSsessionActive'])
1353 self :: addJSconfigParam('keepLSsessionActive',ini_get('session.gc_maxlifetime'));
1356 $GLOBALS['Smarty'] -> assign('LSjsConfig',json_encode(self :: $_JSconfigParams));
1359 $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 1;</script>\n";
1362 $JSscript_txt.="<script type='text/javascript'>LSdebug_active = 0;</script>\n";
1365 $GLOBALS['Smarty'] -> assign('LSsession_js',$JSscript_txt);
1368 self :: addCssFile("LSdefault.css");
1370 foreach (self :: $CssFiles as $file) {
1371 if (!$file['path']) {
1372 $file['path']=LS_CSS_DIR.'/';
1374 $Css_txt.="<link rel='stylesheet' type='text/css' href='".$file['path'].$file['file']."' />\n";
1376 $GLOBALS['Smarty'] -> assign('LSsession_css',$Css_txt);
1378 if (isset(self :: $LSaccess[self :: $topDn])) {
1379 $GLOBALS['Smarty'] -> assign('LSaccess',self :: $LSaccess[self :: $topDn]);
1383 $listTopDn = self :: getSubDnLdapServer();
1384 if (is_array($listTopDn)) {
1386 $GLOBALS['Smarty'] -> assign('label_level',self :: getSubDnLabel());
1387 $GLOBALS['Smarty'] -> assign('_refresh',_('Refresh'));
1388 $LSsession_topDn_index = array();
1389 $LSsession_topDn_name = array();
1390 foreach($listTopDn as $index => $name) {
1391 $LSsession_topDn_index[] = $index;
1392 $LSsession_topDn_name[] = $name;
1394 $GLOBALS['Smarty'] -> assign('LSsession_subDn_indexes',$LSsession_topDn_index);
1395 $GLOBALS['Smarty'] -> assign('LSsession_subDn_names',$LSsession_topDn_name);
1396 $GLOBALS['Smarty'] -> assign('LSsession_subDn',self :: $topDn);
1397 $GLOBALS['Smarty'] -> assign('LSsession_subDnName',self :: getSubDnName());
1400 $GLOBALS['Smarty'] -> assign('LSlanguages',self :: getLangList());
1401 $GLOBALS['Smarty'] -> assign('LSlang',self :: $lang);
1402 $GLOBALS['Smarty'] -> assign('LSencoding',self :: $encoding);
1403 $GLOBALS['Smarty'] -> assign('lang_label',_('Language'));
1405 $GLOBALS['Smarty'] -> assign('displayLogoutBtn',self :: $authParams['displayLogoutBtn']);
1408 if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
1409 $txt_infos="<ul>\n";
1410 foreach($_SESSION['LSsession_infos'] as $info) {
1411 $txt_infos.="<li>$info</li>\n";
1413 $txt_infos.="</ul>\n";
1414 $GLOBALS['Smarty'] -> assign('LSinfos',$txt_infos);
1415 $_SESSION['LSsession_infos']=array();
1418 if (self :: $ajaxDisplay) {
1419 $GLOBALS['Smarty'] -> assign('LSerror_txt',LSerror :: getErrors());
1420 $GLOBALS['Smarty'] -> assign('LSdebug_txt',LSdebug_print(true));
1423 LSerror :: display();
1426 if (!self :: $template)
1427 self :: setTemplate('empty.tpl');
1429 $GLOBALS['Smarty'] -> assign('connected_as',_("Connected as"));
1431 $GLOBALS['Smarty'] -> display(self :: $template);
1435 * Défini que l'affichage se fera ou non via un retour Ajax
1437 * @param[in] $val boolean True pour que l'affichage se fasse par un retour
1441 public static function setAjaxDisplay($val=true) {
1442 self :: $ajaxDisplay = (boolean)$val;
1446 * Affiche un retour Ajax
1450 public static function displayAjaxReturn($data=array()) {
1451 if (isset($data['LSredirect']) && (!LSdebugDefined()) ) {
1452 echo json_encode($data);
1456 $data['LSjsConfig'] = self :: $_JSconfigParams;
1459 if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) {
1460 $txt_infos="<ul>\n";
1461 foreach($_SESSION['LSsession_infos'] as $info) {
1462 $txt_infos.="<li>$info</li>\n";
1464 $txt_infos.="</ul>\n";
1465 $data['LSinfos'] = $txt_infos;
1466 $_SESSION['LSsession_infos']=array();
1469 if (LSerror :: errorsDefined()) {
1470 $data['LSerror'] = LSerror :: getErrors();
1473 if (isset($_REQUEST['imgload'])) {
1474 $data['imgload'] = $_REQUEST['imgload'];
1477 if (LSdebugDefined()) {
1478 $data['LSdebug'] = LSdebug_print(true,false);
1481 echo json_encode($data);
1485 * Retournne un template Smarty compilé
1487 * @param[in] string $template Le template à retourner
1488 * @param[in] array $variables Variables Smarty à assigner avant l'affichage
1490 * @retval string Le HTML compilé du template
1492 public static function fetchTemplate($template,$variables=array()) {
1493 foreach($variables as $name => $val) {
1494 $GLOBALS['Smarty'] -> assign($name,$val);
1496 return $GLOBALS['Smarty'] -> fetch($template);
1500 * Charge les droits LS de l'utilisateur
1502 * @retval boolean True si le chargement à réussi, false sinon.
1504 private static function loadLSprofiles() {
1505 if (is_array(self :: $ldapServer['LSprofiles'])) {
1506 foreach (self :: $ldapServer['LSprofiles'] as $profile => $profileInfos) {
1507 if (is_array($profileInfos)) {
1508 foreach ($profileInfos as $topDn => $rightsInfos) {
1510 * If $topDn == 'LSobject', we search for each LSobject type to find
1511 * all items on witch the user will have powers.
1513 if ($topDn == 'LSobjects') {
1514 if (is_array($rightsInfos)) {
1515 foreach ($rightsInfos as $LSobject => $listInfos) {
1516 if (self :: loadLSclass('LSsearch')) {
1517 if ($listInfos['filter']) {
1518 $filter = self :: getLSuserObject() -> getFData($listInfos['filter']);
1521 $filter = '('.$listInfos['attr'].'='.self :: getLSuserObject() -> getFData($listInfos['attr_value']).')';
1525 'basedn' => $listInfos['basedn'],
1529 if (is_array($listInfos['params'])) {
1530 $params = array_merge($listInfos['params'],$params);
1533 $LSsearch = new LSsearch($LSobject,'LSsession :: loadLSprofiles',$params,true);
1534 $LSsearch -> run(false);
1536 $LSprofiles[$profile] = $LSsearch -> listObjectsDn();
1541 LSdebug('LSobjects => [] doit etre un tableau');
1545 if (is_array($rightsInfos)) {
1546 foreach($rightsInfos as $dn => $conf) {
1547 if ((isset($conf['attr'])) && (isset($conf['LSobject']))) {
1548 if( self :: loadLSobject($conf['LSobject']) ) {
1549 if ($object = new $conf['LSobject']()) {
1550 if ($object -> loadData($dn)) {
1551 $listDns=$object -> getValue($conf['attr']);
1552 $valKey = (isset($conf['attr_value']))?$conf['attr_value']:'%{dn}';
1553 $val = self :: getLSuserObject() -> getFData($valKey);
1554 if (is_array($listDns)) {
1555 if (in_array($val,$listDns)) {
1556 self :: $LSprofiles[$profile][] = $topDn;
1561 LSdebug('Impossible de chargé le dn : '.$dn);
1565 LSdebug('Impossible de créer l\'objet de type : '.$conf['LSobject']);
1570 if (self :: $dn == $dn) {
1571 self :: $LSprofiles[$profile][] = $topDn;
1577 if ( self :: $dn == $rightsInfos ) {
1578 self :: $LSprofiles[$profile][] = $topDn;
1581 } // fin else ($topDn == 'LSobjects')
1582 } // fin foreach($profileInfos)
1583 } // fin is_array($profileInfos)
1584 } // fin foreach LSprofiles
1585 LSdebug(self :: $LSprofiles);
1594 * Charge les droits d'accès de l'utilisateur pour construire le menu de l'interface
1598 private static function loadLSaccess() {
1600 if (is_array(self :: $ldapServer['subDn'])) {
1601 foreach(self :: $ldapServer['subDn'] as $name => $config) {
1602 if ($name=='LSobject') {
1603 if (is_array($config)) {
1605 // Définition des subDns
1606 foreach($config as $objectType => $objectConf) {
1607 if (self :: loadLSobject($objectType)) {
1608 if ($subdnobject = new $objectType()) {
1609 $tbl = $subdnobject -> getSelectArray(NULL,self::getRootDn(),NULL,NULL,false);
1610 if (is_array($tbl)) {
1611 // Définition des accès
1613 if (is_array($objectConf['LSobjects'])) {
1614 foreach($objectConf['LSobjects'] as $type) {
1615 if (self :: loadLSobject($type)) {
1616 if (self :: canAccess($type)) {
1617 $access[$type] = LSconfig :: get('LSobjects.'.$type.'.label');
1622 foreach($tbl as $dn => $dn_name) {
1623 $LSaccess[$dn]=$access;
1632 if ((isCompatibleDNs(self :: $ldapServer['ldap_config']['basedn'],$config['dn']))&&($config['dn']!='')) {
1634 if (is_array($config['LSobjects'])) {
1635 foreach($config['LSobjects'] as $objectType) {
1636 if (self :: loadLSobject($objectType)) {
1637 if (self :: canAccess($objectType)) {
1638 $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label');
1643 $LSaccess[$config['dn']]=$access;
1649 if(is_array(self :: $ldapServer['LSaccess'])) {
1651 foreach(self :: $ldapServer['LSaccess'] as $objectType) {
1652 if (self :: loadLSobject($objectType)) {
1653 if (self :: canAccess($objectType)) {
1654 $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label');
1658 $LSaccess[self :: $topDn] = $access;
1661 foreach($LSaccess as $dn => $access) {
1662 $LSaccess[$dn] = array_merge(
1664 'SELF' => 'My account'
1670 self :: $LSaccess = $LSaccess;
1671 $_SESSION['LSsession']['LSaccess'] = $LSaccess;
1675 * Dit si l'utilisateur est du profil pour le DN spécifié
1677 * @param[in] string $profile de l'objet
1678 * @param[in] string $dn DN de l'objet
1680 * @retval boolean True si l'utilisateur est du profil sur l'objet, false sinon.
1682 public static function isLSprofile($dn,$profile) {
1683 if (is_array(self :: $LSprofiles[$profile])) {
1684 foreach(self :: $LSprofiles[$profile] as $topDn) {
1688 else if ( isCompatibleDNs($dn,$topDn) ) {
1697 * Retourne qui est l'utilisateur par rapport à l'object
1699 * @param[in] string Le DN de l'objet
1701 * @retval string 'admin'/'self'/'user' pour Admin , l'utilisateur lui même ou un simple utilisateur
1703 public static function whoami($dn) {
1704 $retval = array('user');
1706 foreach(self :: $LSprofiles as $profile => $infos) {
1707 if(self :: isLSprofile($dn,$profile)) {
1712 if (self :: $dn == $dn) {
1720 * Retourne le droit de l'utilisateur à accèder à un objet
1722 * @param[in] string $LSobject Le type de l'objet
1723 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1724 * @param[in] string $right Le type de droit d'accès à tester ('r'/'w')
1725 * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1727 * @retval boolean True si l'utilisateur a accès, false sinon
1729 public static function canAccess($LSobject,$dn=NULL,$right=NULL,$attr=NULL) {
1730 if (!self :: loadLSobject($LSobject)) {
1734 $whoami = self :: whoami($dn);
1735 if ($dn==self :: getLSuserObject() -> getValue('dn')) {
1736 if (!self :: in_menu('SELF')) {
1741 $obj = new $LSobject();
1743 if (!self :: in_menu($LSobject,$obj -> subDnValue)) {
1749 $objectdn=LSconfig :: get('LSobjects.'.$LSobject.'.container_dn').','.self :: $topDn;
1750 $whoami = self :: whoami($objectdn);
1753 // Pour un attribut particulier
1756 $attr=LSconfig :: get('LSobjects.'.$LSobject.'.rdn');
1758 if (!is_array(LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr))) {
1763 foreach($whoami as $who) {
1764 $nr = LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr.'.rights.'.$who);
1768 else if($nr == 'r') {
1775 if (($right=='r')||($right=='w')) {
1782 if ( ($r=='r') || ($r=='w') ) {
1789 // Pour un attribut quelconque
1790 $attrs_conf=LSconfig :: get('LSobjects.'.$LSobject.'.attrs');
1791 if (is_array($attrs_conf)) {
1792 if (($right=='r')||($right=='w')) {
1793 foreach($whoami as $who) {
1794 foreach ($attrs_conf as $attr_name => $attr_config) {
1795 if ($attr_config['rights'][$who]==$right) {
1802 foreach($whoami as $who) {
1803 foreach ($attrs_conf as $attr_name => $attr_config) {
1804 if ( ($attr_config['rights'][$who]=='r') || ($attr_config['rights'][$who]=='w') ) {
1815 * Retourne le droit de l'utilisateur à editer à un objet
1817 * @param[in] string $LSobject Le type de l'objet
1818 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1819 * @param[in] string $attr Le nom de l'attribut auquel on test l'accès
1821 * @retval boolean True si l'utilisateur a accès, false sinon
1823 public static function canEdit($LSobject,$dn=NULL,$attr=NULL) {
1824 return self :: canAccess($LSobject,$dn,'w',$attr);
1828 * Retourne le droit de l'utilisateur à supprimer un objet
1830 * @param[in] string $LSobject Le type de l'objet
1831 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1833 * @retval boolean True si l'utilisateur a accès, false sinon
1835 public static function canRemove($LSobject,$dn) {
1836 return self :: canAccess($LSobject,$dn,'w','rdn');
1840 * Retourne le droit de l'utilisateur à créer un objet
1842 * @param[in] string $LSobject Le type de l'objet
1844 * @retval boolean True si l'utilisateur a accès, false sinon
1846 public static function canCreate($LSobject) {
1847 return self :: canAccess($LSobject,NULL,'w','rdn');
1851 * Retourne le droit de l'utilisateur à gérer la relation d'objet
1853 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1854 * @param[in] string $LSobject Le type de l'objet
1855 * @param[in] string $relationName Le nom de la relation avec l'objet
1856 * @param[in] string $right Le type de droit a vérifier ('r' ou 'w')
1858 * @retval boolean True si l'utilisateur a accès, false sinon
1860 public static function relationCanAccess($dn,$LSobject,$relationName,$right=NULL) {
1861 $relConf=LSconfig :: get('LSobjects.'.$LSobject.'.LSrelation.'.$relationName);
1862 if (!is_array($relConf))
1864 $whoami = self :: whoami($dn);
1866 if (($right=='w') || ($right=='r')) {
1868 foreach($whoami as $who) {
1869 $nr = $relConf['rights'][$who];
1873 else if($nr == 'r') {
1885 foreach($whoami as $who) {
1886 if (($relConf['rights'][$who] == 'w') || ($relConf['rights'][$who] == 'r')) {
1895 * Retourne le droit de l'utilisateur à modifier la relation d'objet
1897 * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut)
1898 * @param[in] string $LSobject Le type de l'objet
1899 * @param[in] string $relationName Le nom de la relation avec l'objet
1901 * @retval boolean True si l'utilisateur a accès, false sinon
1903 public static function relationCanEdit($dn,$LSobject,$relationName) {
1904 return self :: relationCanAccess($dn,$LSobject,$relationName,'w');
1908 * Ajoute un fichier temporaire
1910 * @author Benjamin Renard <brenard@easter-eggs.com>
1914 public static function addTmpFile($value,$filePath) {
1915 $hash = mhash(MHASH_MD5,$value);
1916 self :: $tmp_file[$filePath] = $hash;
1917 $_SESSION['LSsession']['tmp_file'][$filePath] = $hash;
1921 * Retourne le chemin du fichier temporaire si l'existe
1923 * @author Benjamin Renard <brenard@easter-eggs.com>
1925 * @param[in] $value La valeur du fichier
1929 public static function tmpFileExist($value) {
1930 $hash = mhash(MHASH_MD5,$value);
1931 foreach(self :: $tmp_file as $filePath => $contentHash) {
1932 if ($hash == $contentHash) {
1940 * Retourne le chemin du fichier temporaire
1942 * Retourne le chemin du fichier temporaire qu'il créera à partir de la valeur
1943 * s'il n'existe pas déjà .
1945 * @author Benjamin Renard <brenard@easter-eggs.com>
1947 * @param[in] $value La valeur du fichier
1951 public static function getTmpFile($value) {
1952 $exist = self :: tmpFileExist($value);
1954 $img_path = LS_TMP_DIR .rand().'.tmp';
1955 $fp = fopen($img_path, "w");
1956 fwrite($fp, $value);
1958 self :: addTmpFile($value,$img_path);
1967 * Supprime les fichiers temporaires
1969 * @author Benjamin Renard <brenard@easter-eggs.com>
1973 public static function deleteTmpFile($filePath=NULL) {
1976 unset(self :: $tmp_file[$filePath]);
1977 unset($_SESSION['LSsession']['tmp_file'][$filePath]);
1980 foreach(self :: $tmp_file as $file => $content) {
1983 self :: $tmp_file = array();
1984 $_SESSION['LSsession']['tmp_file'] = array();
1989 * Retourne true si le cache des droits est activé
1991 * @author Benjamin Renard <brenard@easter-eggs.com>
1993 * @retval boolean True si le cache des droits est activé, false sinon.
1995 public static function cacheLSprofiles() {
1996 return ( (LSconfig :: get('cacheLSprofiles')) || (self :: $ldapServer['cacheLSprofiles']) );
2000 * Retourne true si le cache des subDn est activé
2002 * @author Benjamin Renard <brenard@easter-eggs.com>
2004 * @retval boolean True si le cache des subDn est activé, false sinon.
2006 public static function cacheSudDn() {
2007 return ( (LSconfig :: get('cacheSubDn')) || (self :: $ldapServer['cacheSubDn']));
2011 * Retourne true si le cache des recherches est activé
2013 * @author Benjamin Renard <brenard@easter-eggs.com>
2015 * @retval boolean True si le cache des recherches est activé, false sinon.
2017 public static function cacheSearch() {
2018 return ( (LSconfig :: get('cacheSearch')) || (self :: $ldapServer['cacheSearch']));
2022 * Retourne le label des niveaux pour le serveur ldap courant
2024 * @author Benjamin Renard <brenard@easter-eggs.com>
2026 * @retval string Le label des niveaux pour le serveur ldap dourant
2028 public static function getSubDnLabel() {
2029 return (self :: $ldapServer['subDnLabel']!='')?__(self :: $ldapServer['subDnLabel']):_('Level');
2033 * Retourne le nom du subDn
2035 * @param[in] $subDn string subDn
2037 * @retval string Le nom du subDn ou '' sinon
2039 public static function getSubDnName($subDn=false) {
2041 $subDn = self :: $topDn;
2043 if (self :: getSubDnLdapServer()) {
2044 if (isset(self :: $_subDnLdapServer[self :: $ldapServerId][$subDn])) {
2045 return self :: $_subDnLdapServer[self :: $ldapServerId][$subDn];
2052 * L'objet est t-il utilisé pour listé les subDnS
2054 * @param[in] $type string Le type d'objet
2056 * @retval boolean true si le type d'objet est un subDnObject, false sinon
2058 public static function isSubDnLSobject($type) {
2060 if (is_array(self :: $ldapServer['subDn']['LSobject'])) {
2061 foreach(self :: $ldapServer['subDn']['LSobject'] as $key => $value) {
2071 * Indique si un type d'objet est dans le menu courant
2073 * @retval boolean true si le type d'objet est dans le menu, false sinon
2075 public static function in_menu($LSobject,$topDn=NULL) {
2077 $topDn=self :: $topDn;
2079 return isset(self :: $LSaccess[$topDn][$LSobject]);
2083 * Indique si le serveur LDAP courant a des subDn
2085 * @retval boolean true si le serveur LDAP courant a des subDn, false sinon
2087 public static function haveSubDn() {
2088 return (is_array(self :: $ldapServer['subDn']));
2092 * Ajoute une information à afficher
2094 * @param[in] $msg string Le message à afficher
2098 public static function addInfo($msg) {
2099 $_SESSION['LSsession_infos'][]=$msg;
2103 * Redirection de l'utilisateur vers une autre URL
2105 * @param[in] $url string L'URL
2106 * @param[in] $exit boolean Si true, l'execution script s'arrête après la redirection
2110 public static function redirect($url,$exit=true) {
2111 $GLOBALS['Smarty'] -> assign('url',$url);
2112 $GLOBALS['Smarty'] -> display('redirect.tpl');
2119 * Retourne l'adresse mail d'emission configurée pour le serveur courant
2121 * @retval string Adresse mail d'emission
2123 public static function getEmailSender() {
2124 return self :: $ldapServer['emailSender'];
2128 * Ajout d'une information d'aide
2130 * @param[in] $group string Le nom du groupe d'infos dans lequels ajouter
2132 * @param[in] $infos array Tableau array(name => value) des infos
2136 public static function addHelpInfos($group,$infos) {
2137 if (is_array($infos)) {
2138 if (is_array(self :: $_JSconfigParams['helpInfos'][$group])) {
2139 self :: $_JSconfigParams['helpInfos'][$group] = array_merge(self :: $_JSconfigParams['helpInfos'][$group],$infos);
2142 self :: $_JSconfigParams['helpInfos'][$group] = $infos;
2148 * Défini les codes erreur relative à la classe LSsession
2152 private static function defineLSerrors() {
2156 LSerror :: defineError('LSsession_01',
2157 _("LSsession : The constant %{const} is not defined.")
2159 LSerror :: defineError('LSsession_02',
2160 _("LSsession : The %{addon} support is uncertain. Verify system compatibility and the add-on configuration.")
2162 LSerror :: defineError('LSsession_03',
2163 _("LSsession : LDAP server's configuration data are invalid. Can't connect.")
2165 LSerror :: defineError('LSsession_04',
2166 _("LSsession : Failed to load LSobject type %{type} : unknon type.")
2168 LSerror :: defineError('LSsession_05',
2169 _("LSsession : Failed to load LSclass %{class}.")
2171 LSerror :: defineError('LSsession_06',
2172 _("LSsession : Login or password incorrect.")
2174 LSerror :: defineError('LSsession_07',
2175 _("LSsession : Impossible to identify you : Duplication of identities.")
2177 LSerror :: defineError('LSsession_08',
2178 _("LSsession : Can't load class of authentification (%{class}).")
2180 LSerror :: defineError('LSsession_09',
2181 _("LSsession : Can't connect to LDAP server.")
2183 LSerror :: defineError('LSsession_10',
2184 _("LSsession : Impossible to authenticate you.")
2186 LSerror :: defineError('LSsession_11',
2187 _("LSsession : Your are not authorized to do this action.")
2189 LSerror :: defineError('LSsession_12',
2190 _("LSsession : Some informations are missing to display this page.")
2192 // 13 -> 16 : not yet used
2193 LSerror :: defineError('LSsession_17',
2194 _("LSsession : Error during creation of list of levels. Contact administrators. (Code : %{code})")
2196 LSerror :: defineError('LSsession_18',
2197 _("LSsession : The password recovery is disabled for this LDAP server.")
2199 LSerror :: defineError('LSsession_19',
2200 _("LSsession : Some informations are missing to recover your password. Contact administrators.")
2202 LSerror :: defineError('LSsession_20',
2203 _("LSsession : Error during password recovery. Contact administrators.(Step : %{step})")
2205 // 21 : not yet used
2206 LSerror :: defineError('LSsession_22',
2207 _("LSsession : problem during initialisation.")
2212 * Ajax method when change ldapserver on login form
2214 * @param[in] $data array The return data address
2218 public static function ajax_onLdapServerChangedLogin(&$data) {
2219 if ( isset($_REQUEST['server']) ) {
2220 self :: setLdapServer($_REQUEST['server']);
2222 if ( self :: LSldapConnect() ) {
2224 if (isset($_SESSION['LSsession_topDn'])) {
2225 $sel = $_SESSION['LSsession_topDn'];
2230 $list = self :: getSubDnLdapServerOptions($sel);
2231 if (is_string($list)) {
2232 $data['list_topDn'] = "<select name='LSsession_topDn' id='LSsession_topDn'>".$list."</select>";
2233 $data['subDnLabel'] = self :: getSubDnLabel();
2236 $data['recoverPassword'] = isset(self :: $ldapServer['recoverPassword']);
2241 * Ajax method when change ldapserver on recoverPassword form
2243 * @param[in] $data array The return data address
2247 public static function ajax_onLdapServerChangedRecoverPassword(&$data) {
2248 if ( isset($_REQUEST['server']) ) {
2249 self :: setLdapServer($_REQUEST['server']);
2250 $data=array('recoverPassword' => isset(self :: $ldapServer['recoverPassword']));