*/ class LSsession { // La configuration du serveur Ldap utilisé public static $ldapServer = NULL; // L'id du serveur Ldap utilisé private static $ldapServerId = NULL; // Le topDn courant private static $topDn = NULL; // Le DN de l'utilisateur connecté private static $dn = NULL; // Le RDN de l'utilisateur connecté (son identifiant) private static $rdn = NULL; // Les LSprofiles de l'utilisateur private static $LSprofiles = array(); // Les droits d'accès de l'utilisateur private static $LSaccess = array(); // Authentification parameters private static $authParams = array(); // Les fichiers temporaires private static $tmp_file = array(); // Langue et encodage actuel private static $lang = NULL; private static $encoding = NULL; /* * Constante de classe non stockée en session */ // Le template à afficher private static $template = NULL; // Les subDn des serveurs Ldap private static $_subDnLdapServer = array(); // Affichage Ajax private static $ajaxDisplay = false; // Les fichiers JS à charger dans la page private static $JSscripts = array(); // Les paramètres JS à communiquer dans la page private static $_JSconfigParams = array(); // Les fichiers CSS à charger dans la page private static $CssFiles = array(); // L'objet de l'utilisateur connecté private static $LSuserObject = NULL; // The LSauht object of the session private static $LSauthObject = false; /** * Include un fichier PHP * * @author Benjamin Renard * * @retval true si tout c'est bien passé, false sinon */ public static function includeFile($file) { if (!file_exists($file)) { return; } if (defined('LSdebug') && constant('LSdebug')) { return include_once($file); } else { return @include_once($file); } return; } /** * Lancement de LSconfig * * @author Benjamin Renard * * @retval true si tout c'est bien passé, false sinon */ private static function startLSconfig() { if (self :: loadLSclass('LSconfig')) { if (LSconfig :: start()) { return true; } } die("ERROR : Can't load configuration files."); return; } /** * Lancement et initialisation de Smarty * * @author Benjamin Renard * * @retval true si tout c'est bien passé, false sinon */ private static function startLStemplate() { if ( self :: includeFile(LSconfig :: get('Smarty')) ) { $GLOBALS['Smarty'] = new Smarty(); $GLOBALS['Smarty'] -> template_dir = LS_TEMPLATES_DIR; $GLOBALS['Smarty'] -> compile_dir = LS_TMP_DIR; if (LSdebug) { $GLOBALS['Smarty'] -> caching = 0; // cache files are always regenerated $GLOBALS['Smarty'] -> force_compile = TRUE; // recompile template if it is changed $GLOBALS['Smarty'] -> compile_check = TRUE; if (isset($_REQUEST['debug_smarty'])) { // debug smarty $GLOBALS['Smarty'] -> debugging = true; } } $GLOBALS['Smarty'] -> register_function('getFData','smarty_getFData'); $GLOBALS['Smarty'] -> assign('LS_CSS_DIR',LS_CSS_DIR); $GLOBALS['Smarty'] -> assign('LS_IMAGES_DIR',LS_IMAGES_DIR); self :: addJSconfigParam('LS_IMAGES_DIR',LS_IMAGES_DIR); return true; } die("ERROR : Can't load Smarty."); return; } /** * Retourne le topDn de la session * * @author Benjamin Renard * * @retval string le topDn de la session */ public static function getTopDn() { if (!is_null(self :: $topDn)) { return self :: $topDn; } else { return self :: getRootDn(); } } /** * Retourne le rootDn de la session * * @author Benjamin Renard * * @retval string le rootDn de la session */ public static function getRootDn() { return self :: $ldapServer['ldap_config']['basedn']; } /** * Initialisation de la gestion des erreurs * * Création de l'objet LSerror * * @author Benjamin Renard logout(); } session_destroy(); if (is_array($_SESSION['LSsession']['tmp_file'])) { self :: $tmp_file = $_SESSION['LSsession']['tmp_file']; } self :: deleteTmpFile(); unset($_SESSION['LSsession']); self :: redirect('index.php'); return; } self :: getLSuserObject(); if ( !self :: cacheLSprofiles() || isset($_REQUEST['LSsession_refresh']) ) { self :: loadLSaccess(); } $GLOBALS['Smarty'] -> assign('LSsession_username',self :: getLSuserObject() -> getDisplayName()); if (isset ($_POST['LSsession_topDn']) && $_POST['LSsession_topDn']) { if (self :: validSubDnLdapServer($_POST['LSsession_topDn'])) { self :: $topDn = $_POST['LSsession_topDn']; $_SESSION['LSsession']['topDn'] = $_POST['LSsession_topDn']; } // end if } // end if return true; } else { if (isset($_GET['LSsession_recoverPassword'])) { session_destroy(); } // Session inexistante if (isset($_POST['LSsession_ldapserver'])) { self :: setLdapServer($_POST['LSsession_ldapserver']); } else { self :: setLdapServer(0); } // Connexion au serveur LDAP if (self :: LSldapConnect()) { // topDn if ( $_POST['LSsession_topDn'] != '' ){ self :: $topDn = $_POST['LSsession_topDn']; } else { self :: $topDn = self :: $ldapServer['ldap_config']['basedn']; } $_SESSION['LSsession_topDn']=self :: $topDn; if (isset($_GET['LSsession_recoverPassword'])) { $recoveryPasswordInfos = self :: recoverPasswd( $_REQUEST['LSsession_user'], $_GET['recoveryHash'] ); } else { $authObj=self :: getLSauthObject(); if ($authObj) { if ($authObj -> getPostData()) { $LSuserObject = $authObj -> authenticate(); if ($LSuserObject) { // Authentication successful self :: $LSuserObject = $LSuserObject; self :: $dn = $LSuserObject->getValue('dn'); self :: $rdn = $LSuserObject->getValue('rdn'); self :: loadLSprofiles(); self :: loadLSaccess(); $GLOBALS['Smarty'] -> assign('LSsession_username',self :: getLSuserObject() -> getDisplayName()); $_SESSION['LSsession']=self :: getContextInfos(); return true; } } } } } else { LSerror :: addErrorCode('LSsession_09'); } if (self :: $ldapServerId) { $GLOBALS['Smarty'] -> assign('ldapServerId',self :: $ldapServerId); } $GLOBALS['Smarty'] -> assign('topDn',self :: $topDn); if (isset($_GET['LSsession_recoverPassword'])) { self :: displayRecoverPasswordForm($recoveryPasswordInfos); } elseif(self :: $authParams['displayLoginForm']) { self :: displayLoginForm(); } else { self :: setTemplate('blank.tpl'); LSerror :: addErrorCode('LSsession_10'); } return; } } /** * Get LSauthObject * * @retval LSauth object or false **/ private static function getLSauthObject() { if (!self :: $LSauthObject) { if (self :: loadLSauth()) { if (isset(self :: $ldapServer['LSauth']['method'])) { $LSauthClass = 'LSauth'.self :: $ldapServer['LSauth']['method']; if (!self :: loadLSauth(self :: $ldapServer['LSauth']['method'])) { LSerror :: addErrorCode('LSsession_08',self :: $ldapServer['LSauth']['method']); $LSauthClass = 'LSauth'; } } else { $LSauthClass = 'LSauth'; } self :: $LSauthObject = new $LSauthClass(); self :: $authParams = self :: $LSauthObject->params; } } return self :: $LSauthObject; } /** * Do recover password * * @param[in] $username string The submited username * @param[in] $recoveryHash string The submited recoveryHash * * @retval array The recoveryPassword infos for template **/ private static function recoverPasswd($username,$recoveryHash) { $recoveryPasswordInfos=array(); if ( self :: loadLSobject(self :: $ldapServer['authObjectType']) ) { $authobject = new self :: $ldapServer['authObjectType'](); if (!empty($recoveryHash)) { $filter=Net_LDAP2_Filter::create( self :: $ldapServer['recoverPassword']['recoveryHashAttr'], 'equals', $recoveryHash ); $result = $authobject -> listObjects($filter,self :: $topDn); } elseif (!empty($username)) { $result = $authobject -> searchObject( $username, self :: $topDn, self :: $ldapServer['authObjectFilter'] ); } else { return $recoveryPasswordInfos; } $nbresult=count($result); if ($nbresult==0) { LSdebug('hash/username incorrect'); LSerror :: addErrorCode('LSsession_06'); } elseif ($nbresult>1) { LSerror :: addErrorCode('LSsession_07'); } else { $rdn = $result[0] -> getValue('rdn'); $username = $rdn[0]; LSdebug('Recover : Id trouvé : '.$username); if (self :: $ldapServer['recoverPassword']) { if (self :: loadLSaddon('mail')) { LSdebug('Récupération active'); $user=$result[0]; $emailAddress = $user -> getValue(self :: $ldapServer['recoverPassword']['mailAttr']); $emailAddress = $emailAddress[0]; if (checkEmail($emailAddress)) { LSdebug('Email : '.$emailAddress); self :: $dn = $user -> getDn(); // 1ère étape : envoie du recoveryHash if (empty($recoveryHash)) { $hash=self :: recoverPasswdFirstStep($user); if ($hash) { if (self :: recoverPasswdSendMail($emailAddress,1,$hash)) { // Mail a bien été envoyé $recoveryPasswordInfos['recoveryHashMail']=$emailAddress; } } } // 2nd étape : génération du mot de passe + envoie par mail else { $pwd=self :: recoverPasswdSecondStep($user); if ($pwd) { if (self :: recoverPasswdSendMail($emailAddress,2,$pwd)){ // Mail a bien été envoyé $recoveryPasswordInfos['newPasswordMail']=$emailAddress; } } } } else { LSerror :: addErrorCode('LSsession_19'); } } } else { LSerror :: addErrorCode('LSsession_18'); } } } return $recoveryPasswordInfos; } /** * Send recover password mail * * @param[in] $mail string The user's mail * @param[in] $step integer The step * @param[in] $info string The info for formatted message * * @retval boolean True on success or False **/ private static function recoverPasswdSendMail($mail,$step,$info) { // Header des mails $sendParams=array(); if (self :: $ldapServer['recoverPassword']['recoveryEmailSender']) { $sendParams['From']=self :: $ldapServer['recoverPassword']['recoveryEmailSender']; } if ($step==1) { if ($_SERVER['HTTPS']=='on') { $recovery_url='https://'; } else { $recovery_url='http://'; } $recovery_url .= $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'&recoveryHash='.$info; $subject = self :: $ldapServer['recoverPassword']['recoveryHashMail']['subject']; $msg = getFData( self :: $ldapServer['recoverPassword']['recoveryHashMail']['msg'], $recovery_url ); } else { $subject = self :: $ldapServer['recoverPassword']['newPasswordMail']['subject']; $msg = getFData( self :: $ldapServer['recoverPassword']['newPasswordMail']['msg'], $info ); } if (!sendMail($mail,$subject,$msg,$sendParams)) { LSdebug("Problème durant l'envoie du mail"); LSerror :: addErrorCode('LSsession_20',4); return; } return true; } /** * Do first step of recovering password * * @param[in] $user LSldapObject The LSldapObject of the user * * @retval string|False The recory hash on success or False **/ private static function recoverPasswdFirstStep($user) { // Generer un hash $rdn=$user -> getValue('rdn'); $rdn = $rdn[0]; $recovery_hash = md5($rdn . strval(time()) . strval(rand())); $lostPasswdForm = $user -> getForm('lostPassword'); $lostPasswdForm -> setPostData( array( self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => $recovery_hash ) ,true ); if($lostPasswdForm -> validate()) { if ($user -> updateData('lostPassword')) { // recoveryHash de l'utilisateur mis à jour return $recovery_hash; } else { // Erreur durant la mise à jour de l'objet LSdebug("Erreur durant la mise à jour de l'objet"); LSerror :: addErrorCode('LSsession_20',6); } } else { // Erreur durant la validation du formulaire de modification de perte de password LSdebug("Erreur durant la validation du formulaire de modification de perte de password"); LSerror :: addErrorCode('LSsession_20',5); } return; } /** * Do second step of recovering password * * @param[in] $user LSldapObject The LSldapObject of the user * * @retval string|False The new password on success or False **/ private static function recoverPasswdSecondStep($user) { $attr=$user -> attrs[self :: $ldapServer['authObjectTypeAttrPwd']]; if ($attr instanceof LSattribute) { $mdp = generatePassword( $attr -> config['html_options']['chars'], $attr -> config['html_options']['lenght'] ); LSdebug('Nvx mpd : '.$mdp); $lostPasswdForm = $user -> getForm('lostPassword'); $lostPasswdForm -> setPostData( array( self :: $ldapServer['recoverPassword']['recoveryHashAttr'] => array(''), self :: $ldapServer['authObjectTypeAttrPwd'] => array($mdp) ) ,true ); if($lostPasswdForm -> validate()) { if ($user -> updateData('lostPassword')) { return $mdp; } else { // Erreur durant la mise à jour de l'objet LSdebug("Erreur durant la mise à jour de l'objet"); LSerror :: addErrorCode('LSsession_20',3); } } else { // Erreur durant la validation du formulaire de modification de perte de password LSdebug("Erreur durant la validation du formulaire de modification de perte de password"); LSerror :: addErrorCode('LSsession_20',2); } } else { // l'attribut password n'existe pas LSdebug("L'attribut password n'existe pas"); LSerror :: addErrorCode('LSsession_20',1); } return; } /** * Retourne les informations du contexte * * @author Benjamin Renard self :: $tmp_file, 'topDn' => self :: $topDn, 'dn' => self :: $dn, 'rdn' => self :: $rdn, 'ldapServerId' => self :: $ldapServerId, 'ldapServer' => self :: $ldapServer, 'LSprofiles' => self :: $LSprofiles, 'LSaccess' => self :: $LSaccess, 'authParams' => self :: $authParams ); } /** * Retourne l'objet de l'utilisateur connecté * * @author Benjamin Renard loadData(self :: $dn); } else { return; } } return self :: $LSuserObject; } /** * Retourne le DN de l'utilisateur connecté * * @author Benjamin Renard getDn(); $rdn = $object -> getValue('rdn'); if(is_array($rdn)) { $rdn = $rdn[0]; } self :: $rdn = $rdn; self :: $LSuserObject = $object; if(self :: loadLSprofiles()) { self :: loadLSaccess(); $_SESSION['LSsession']=self :: getContextInfos(); return true; } } return; } /** * Définition du serveur Ldap de la session * * Définition du serveur Ldap de la session à partir de son ID dans * le tableau LSconfig :: get('ldap_servers'). * * @param[in] integer Index du serveur Ldap * * @retval boolean True sinon false. */ public static function setLdapServer($id) { $conf = LSconfig :: get("ldap_servers.$id"); if ( is_array($conf) ) { self :: $ldapServerId = $id; self :: $ldapServer = $conf; self :: setLocale(); return true; } else { return; } } /** * Connexion au serveur Ldap * * @retval boolean True sinon false. */ public static function LSldapConnect() { if (self :: $ldapServer) { self :: includeFile(LSconfig :: get('NetLDAP2')); if (!self :: loadLSclass('LSldap')) { return; } LSldap :: connect(self :: $ldapServer['ldap_config']); if (LSldap :: isConnected()) { return true; } else { return; } } else { LSerror :: addErrorCode('LSsession_03'); return; } } /** * Use this function to know if subDn is enabled for the curent LdapServer * * @retval boolean **/ public static function subDnIsEnabled() { if (!isset(self :: $ldapServer['subDn'])) { return; } if ( !is_array(self :: $ldapServer['subDn']) ) { return; } return true; } /** * Retourne les sous-dns du serveur Ldap courant * * @retval mixed Tableau des subDn, false si une erreur est survenue. */ public static function getSubDnLdapServer() { if (self :: cacheSudDn() && isset(self :: $_subDnLdapServer[self :: $ldapServerId])) { return self :: $_subDnLdapServer[self :: $ldapServerId]; } if (!self::subDnIsEnabled()) { return; } $return=array(); foreach(self :: $ldapServer['subDn'] as $subDn_name => $subDn_config) { if ($subDn_name == 'LSobject') { if (is_array($subDn_config)) { foreach($subDn_config as $LSobject_name => $LSoject_config) { if ($LSoject_config['basedn']) { $basedn = $LSoject_config['basedn']; } else { $basedn = self::getRootDn(); } if ($LSoject_config['displayName']) { $displayName = $LSoject_config['displayName']; } else { $displayName = NULL; } if( self :: loadLSobject($LSobject_name) ) { if ($subdnobject = new $LSobject_name()) { $tbl_return = $subdnobject -> getSelectArray(NULL,$basedn,$displayName); if (is_array($tbl_return)) { $return=array_merge($return,$tbl_return); } else { LSerror :: addErrorCode('LSsession_17',3); } } else { LSerror :: addErrorCode('LSsession_17',2); } } } } else { LSerror :: addErrorCode('LSsession_17',1); } } else { if ((isCompatibleDNs($subDn_config['dn'],self :: $ldapServer['ldap_config']['basedn']))&&($subDn_config['dn']!="")) { $return[$subDn_config['dn']] = __($subDn_name); } } } if (self :: cacheSudDn()) { self :: $_subDnLdapServer[self :: $ldapServerId]=$return; $_SESSION['LSsession_subDnLdapServer'] = self :: $_subDnLdapServer; } return $return; } /** * Retourne la liste de subDn du serveur Ldap utilise * trié par la profondeur dans l'arboressence (ordre décroissant) * * @return array() Tableau des subDn trié */ public static function getSortSubDnLdapServer() { $subDnLdapServer = self :: getSubDnLdapServer(); if (!$subDnLdapServer) { return array(); } uksort($subDnLdapServer,"compareDn"); return $subDnLdapServer; } /** * Retourne les options d'une liste déroulante pour le choix du topDn * de connexion au serveur Ldap * * Liste les subdn (self :: $ldapServer['subDn']) * * @retval string Les options (\n"; } return $display; } return; } /** * Vérifie qu'un subDn est déclaré * * @param[in] string Un subDn * * @retval boolean True si le subDn existe, False sinon */ public static function validSubDnLdapServer($subDn) { $listTopDn = self :: getSubDnLdapServer(); if(is_array($listTopDn)) { foreach($listTopDn as $dn => $txt) { if ($subDn==$dn) { return true; } // end if } // end foreach } // end if return; } /** * Test un couple LSobject/pwd * * Test un bind sur le serveur avec le dn de l'objet et le mot de passe fourni. * * @param[in] LSobject L'object "user" pour l'authentification * @param[in] string Le mot de passe à tester * * @retval boolean True si l'authentification à réussi, false sinon. */ public static function checkUserPwd($object,$pwd) { return LSldap :: checkBind($object -> getValue('dn'),$pwd); } /** * Affiche le formulaire de login * * Défini les informations pour le template Smarty du formulaire de login. * * @retval void */ public static function displayLoginForm() { $GLOBALS['Smarty'] -> assign('pagetitle',_('Connection')); if (isset($_GET['LSsession_logout'])) { $GLOBALS['Smarty'] -> assign('loginform_action','index.php'); } else { $GLOBALS['Smarty'] -> assign('loginform_action',$_SERVER['REQUEST_URI']); } if (count(LSconfig :: get('ldap_servers'))==1) { $GLOBALS['Smarty'] -> assign('loginform_ldapserver_style','style="display: none"'); } $GLOBALS['Smarty'] -> assign('loginform_label_ldapserver',_('LDAP server')); $ldapservers_name=array(); $ldapservers_index=array(); foreach(LSconfig :: get('ldap_servers') as $id => $infos) { $ldapservers_index[]=$id; $ldapservers_name[]=__($infos['name']); } $GLOBALS['Smarty'] -> assign('loginform_ldapservers_name',$ldapservers_name); $GLOBALS['Smarty'] -> assign('loginform_ldapservers_index',$ldapservers_index); $GLOBALS['Smarty'] -> assign('loginform_label_level',_('Level')); $GLOBALS['Smarty'] -> assign('loginform_label_user',_('Identifier')); $GLOBALS['Smarty'] -> assign('loginform_label_pwd',_('Password')); $GLOBALS['Smarty'] -> assign('loginform_label_submit',_('Connect')); $GLOBALS['Smarty'] -> assign('loginform_label_recoverPassword',_('Forgot your password ?')); self :: setTemplate('login.tpl'); self :: addJSscript('LSsession_login.js'); } /** * Affiche le formulaire de récupération de mot de passe * * Défini les informations pour le template Smarty du formulaire de * récupération de mot de passe * * @param[in] $infos array() Information sur le status du processus de * recouvrement de mot de passe * * @retval void */ public static function displayRecoverPasswordForm($recoveryPasswordInfos) { $GLOBALS['Smarty'] -> assign('pagetitle',_('Recovery of your credentials')); $GLOBALS['Smarty'] -> assign('recoverpasswordform_action','index.php?LSsession_recoverPassword'); if (count(LSconfig :: get('ldap_servers'))==1) { $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapserver_style','style="display: none"'); } $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_ldapserver',_('LDAP server')); $ldapservers_name=array(); $ldapservers_index=array(); foreach(LSconfig :: get('ldap_servers') as $id => $infos) { $ldapservers_index[]=$id; $ldapservers_name[]=$infos['name']; } $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapservers_name',$ldapservers_name); $GLOBALS['Smarty'] -> assign('recoverpasswordform_ldapservers_index',$ldapservers_index); $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_user',_('Identifier')); $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_submit',_('Validate')); $GLOBALS['Smarty'] -> assign('recoverpasswordform_label_back',_('Back')); $recoverpassword_msg = _('Please fill the identifier field to proceed recovery procedure'); if (isset($recoveryPasswordInfos['recoveryHashMail'])) { $recoverpassword_msg = getFData( _("An email has been sent to %{mail}. " . "Please follow the instructions on it."), $recoveryPasswordInfos['recoveryHashMail'] ); } if (isset($recoveryPasswordInfos['newPasswordMail'])) { $recoverpassword_msg = getFData( _("Your new password has been sent to %{mail}. "), $recoveryPasswordInfos['newPasswordMail'] ); } $GLOBALS['Smarty'] -> assign('recoverpassword_msg',$recoverpassword_msg); self :: setTemplate('recoverpassword.tpl'); self :: addJSscript('LSsession_recoverPassword.js'); } /** * Défini le template Smarty à utiliser * * Remarque : les fichiers de templates doivent se trouver dans le dossier * templates/. * * @param[in] string Le nom du fichier de template * * @retval void */ public static function setTemplate($template) { self :: $template = $template; } /** * Ajoute un script JS au chargement de la page * * Remarque : les scripts doivents être dans le dossier LS_JS_DIR. * * @param[in] $script Le nom du fichier de script à charger. * * @retval void */ public static function addJSscript($file,$path=NULL) { $script=array( 'file' => $file, 'path' => $path ); self :: $JSscripts[$path.$file]=$script; } /** * Ajouter un paramètre de configuration Javascript * * @param[in] $name string Nom de la variable de configuration * @param[in] $val mixed Valeur de la variable de configuration * * @retval void */ public static function addJSconfigParam($name,$val) { self :: $_JSconfigParams[$name]=$val; } /** * Ajoute une feuille de style au chargement de la page * * Remarque : les scripts doivents être dans le dossier LS_CSS_DIR. * * @param[in] $script Le nom du fichier css à charger. * * @retval void */ public static function addCssFile($file,$path=NULL) { $cssFile=array( 'file' => $file, 'path' => $path ); self :: $CssFiles[$path.$file]=$cssFile; } /** * Affiche le template Smarty * * Charge les dépendances et affiche le template Smarty * * @retval void */ public static function displayTemplate() { // JS $JSscript_txt=''; foreach ($GLOBALS['defaultJSscipts'] as $script) { $JSscript_txt.="\n"; } foreach (self :: $JSscripts as $script) { if (!$script['path']) { $script['path']=LS_JS_DIR; } else { $script['path'].='/'; } $JSscript_txt.="\n"; } $KAconf = LSconfig :: get('keepLSsessionActive'); if ( ( (!isset(self :: $ldapServer['keepLSsessionActive'])) && (!($KAconf === false)) ) || (self :: $ldapServer['keepLSsessionActive']) ) { self :: addJSconfigParam('keepLSsessionActive',ini_get('session.gc_maxlifetime')); } $GLOBALS['Smarty'] -> assign('LSjsConfig',json_encode(self :: $_JSconfigParams)); if (LSdebug) { $JSscript_txt.="\n"; } else { $JSscript_txt.="\n"; } $GLOBALS['Smarty'] -> assign('LSsession_js',$JSscript_txt); // Css self :: addCssFile("LSdefault.css"); $Css_txt=''; foreach (self :: $CssFiles as $file) { if (!$file['path']) { $file['path']=LS_CSS_DIR.'/'; } $Css_txt.="\n"; } $GLOBALS['Smarty'] -> assign('LSsession_css',$Css_txt); if (isset(self :: $LSaccess[self :: $topDn])) { $GLOBALS['Smarty'] -> assign('LSaccess',self :: $LSaccess[self :: $topDn]); } // Niveau $listTopDn = self :: getSubDnLdapServer(); if (is_array($listTopDn)) { asort($listTopDn); $GLOBALS['Smarty'] -> assign('label_level',self :: getSubDnLabel()); $GLOBALS['Smarty'] -> assign('_refresh',_('Refresh')); $LSsession_topDn_index = array(); $LSsession_topDn_name = array(); foreach($listTopDn as $index => $name) { $LSsession_topDn_index[] = $index; $LSsession_topDn_name[] = $name; } $GLOBALS['Smarty'] -> assign('LSsession_subDn_indexes',$LSsession_topDn_index); $GLOBALS['Smarty'] -> assign('LSsession_subDn_names',$LSsession_topDn_name); $GLOBALS['Smarty'] -> assign('LSsession_subDn',self :: $topDn); $GLOBALS['Smarty'] -> assign('LSsession_subDnName',self :: getSubDnName()); } $GLOBALS['Smarty'] -> assign('LSlanguages',self :: getLangList()); $GLOBALS['Smarty'] -> assign('LSlang',self :: $lang); $GLOBALS['Smarty'] -> assign('LSencoding',self :: $encoding); $GLOBALS['Smarty'] -> assign('lang_label',_('Language')); $GLOBALS['Smarty'] -> assign('displayLogoutBtn',self :: $authParams['displayLogoutBtn']); // Infos if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) { $txt_infos="
    \n"; foreach($_SESSION['LSsession_infos'] as $info) { $txt_infos.="
  • $info
  • \n"; } $txt_infos.="
\n"; $GLOBALS['Smarty'] -> assign('LSinfos',$txt_infos); $_SESSION['LSsession_infos']=array(); } if (self :: $ajaxDisplay) { $GLOBALS['Smarty'] -> assign('LSerror_txt',LSerror :: getErrors()); $GLOBALS['Smarty'] -> assign('LSdebug_txt',LSdebug_print(true)); } else { LSerror :: display(); LSdebug_print(); } if (!self :: $template) self :: setTemplate('empty.tpl'); $GLOBALS['Smarty'] -> assign('connected_as',_("Connected as")); $GLOBALS['Smarty'] -> display(self :: $template); } /** * Défini que l'affichage se fera ou non via un retour Ajax * * @param[in] $val boolean True pour que l'affichage se fasse par un retour * Ajax, false sinon * @retval void */ public static function setAjaxDisplay($val=true) { self :: $ajaxDisplay = (boolean)$val; } /** * Affiche un retour Ajax * * @retval void */ public static function displayAjaxReturn($data=array()) { if (isset($data['LSredirect']) && (!LSdebugDefined()) ) { echo json_encode($data); return; } $data['LSjsConfig'] = self :: $_JSconfigParams; // Infos if((!empty($_SESSION['LSsession_infos']))&&(is_array($_SESSION['LSsession_infos']))) { $txt_infos="
    \n"; foreach($_SESSION['LSsession_infos'] as $info) { $txt_infos.="
  • $info
  • \n"; } $txt_infos.="
\n"; $data['LSinfos'] = $txt_infos; $_SESSION['LSsession_infos']=array(); } if (LSerror :: errorsDefined()) { $data['LSerror'] = LSerror :: getErrors(); } if (isset($_REQUEST['imgload'])) { $data['imgload'] = $_REQUEST['imgload']; } if (LSdebugDefined()) { $data['LSdebug'] = LSdebug_print(true,false); } echo json_encode($data); } /** * Retournne un template Smarty compilé * * @param[in] string $template Le template à retourner * @param[in] array $variables Variables Smarty à assigner avant l'affichage * * @retval string Le HTML compilé du template */ public static function fetchTemplate($template,$variables=array()) { foreach($variables as $name => $val) { $GLOBALS['Smarty'] -> assign($name,$val); } return $GLOBALS['Smarty'] -> fetch($template); } /** * Charge les droits LS de l'utilisateur * * @retval boolean True si le chargement à réussi, false sinon. **/ private static function loadLSprofiles() { if (is_array(self :: $ldapServer['LSprofiles'])) { foreach (self :: $ldapServer['LSprofiles'] as $profile => $profileInfos) { if (is_array($profileInfos)) { foreach ($profileInfos as $topDn => $rightsInfos) { /* * If $topDn == 'LSobject', we search for each LSobject type to find * all items on witch the user will have powers. */ if ($topDn == 'LSobjects') { if (is_array($rightsInfos)) { foreach ($rightsInfos as $LSobject => $listInfos) { if (self :: loadLSclass('LSsearch')) { if ($listInfos['filter']) { $filter = self :: getLSuserObject() -> getFData($listInfos['filter']); } else { $filter = '('.$listInfos['attr'].'='.self :: getLSuserObject() -> getFData($listInfos['attr_value']).')'; } $params = array ( 'basedn' => $listInfos['basedn'], 'filter' => $filter ); if (is_array($listInfos['params'])) { $params = array_merge($listInfos['params'],$params); } $LSsearch = new LSsearch($LSobject,'LSsession :: loadLSprofiles',$params,true); $LSsearch -> run(false); $LSprofiles[$profile] = $LSsearch -> listObjectsDn(); } } } else { LSdebug('LSobjects => [] doit etre un tableau'); } } else { if (is_array($rightsInfos)) { foreach($rightsInfos as $dn => $conf) { if ((isset($conf['attr'])) && (isset($conf['LSobject']))) { if( self :: loadLSobject($conf['LSobject']) ) { if ($object = new $conf['LSobject']()) { if ($object -> loadData($dn)) { $listDns=$object -> getValue($conf['attr']); $valKey = (isset($conf['attr_value']))?$conf['attr_value']:'%{dn}'; $val = self :: getLSuserObject() -> getFData($valKey); if (is_array($listDns)) { if (in_array($val,$listDns)) { self :: $LSprofiles[$profile][] = $topDn; } } } else { LSdebug('Impossible de chargé le dn : '.$dn); } } else { LSdebug('Impossible de créer l\'objet de type : '.$conf['LSobject']); } } } else { if (self :: $dn == $dn) { self :: $LSprofiles[$profile][] = $topDn; } } } } else { if ( self :: $dn == $rightsInfos ) { self :: $LSprofiles[$profile][] = $topDn; } } } // fin else ($topDn == 'LSobjects') } // fin foreach($profileInfos) } // fin is_array($profileInfos) } // fin foreach LSprofiles LSdebug(self :: $LSprofiles); return true; } else { return; } } /** * Charge les droits d'accès de l'utilisateur pour construire le menu de l'interface * * @retval void */ private static function loadLSaccess() { $LSaccess=array(); if (is_array(self :: $ldapServer['subDn'])) { foreach(self :: $ldapServer['subDn'] as $name => $config) { if ($name=='LSobject') { if (is_array($config)) { // Définition des subDns foreach($config as $objectType => $objectConf) { if (self :: loadLSobject($objectType)) { if ($subdnobject = new $objectType()) { $tbl = $subdnobject -> getSelectArray(NULL,self::getRootDn(),NULL,NULL,false); if (is_array($tbl)) { // Définition des accès $access=array(); if (is_array($objectConf['LSobjects'])) { foreach($objectConf['LSobjects'] as $type) { if (self :: loadLSobject($type)) { if (self :: canAccess($type)) { $access[$type] = LSconfig :: get('LSobjects.'.$type.'.label'); } } } } foreach($tbl as $dn => $dn_name) { $LSaccess[$dn]=$access; } } } } } } } else { if ((isCompatibleDNs(self :: $ldapServer['ldap_config']['basedn'],$config['dn']))&&($config['dn']!='')) { $access=array(); if (is_array($config['LSobjects'])) { foreach($config['LSobjects'] as $objectType) { if (self :: loadLSobject($objectType)) { if (self :: canAccess($objectType)) { $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label'); } } } } $LSaccess[$config['dn']]=$access; } } } } else { if(is_array(self :: $ldapServer['LSaccess'])) { $access=array(); foreach(self :: $ldapServer['LSaccess'] as $objectType) { if (self :: loadLSobject($objectType)) { if (self :: canAccess($objectType)) { $access[$objectType] = LSconfig :: get('LSobjects.'.$objectType.'.label'); } } } $LSaccess[self :: $topDn] = $access; } } foreach($LSaccess as $dn => $access) { $LSaccess[$dn] = array_merge( array( 'SELF' => 'My account' ), $access ); } self :: $LSaccess = $LSaccess; $_SESSION['LSsession']['LSaccess'] = $LSaccess; } /** * Dit si l'utilisateur est du profil pour le DN spécifié * * @param[in] string $profile de l'objet * @param[in] string $dn DN de l'objet * * @retval boolean True si l'utilisateur est du profil sur l'objet, false sinon. */ public static function isLSprofile($dn,$profile) { if (is_array(self :: $LSprofiles[$profile])) { foreach(self :: $LSprofiles[$profile] as $topDn) { if($dn == $topDn) { return true; } else if ( isCompatibleDNs($dn,$topDn) ) { return true; } } } return; } /** * Retourne qui est l'utilisateur par rapport à l'object * * @param[in] string Le DN de l'objet * * @retval string 'admin'/'self'/'user' pour Admin , l'utilisateur lui même ou un simple utilisateur */ public static function whoami($dn) { $retval = array('user'); foreach(self :: $LSprofiles as $profile => $infos) { if(self :: isLSprofile($dn,$profile)) { $retval[]=$profile; } } if (self :: $dn == $dn) { $retval[]='self'; } return $retval; } /** * Retourne le droit de l'utilisateur à accèder à un objet * * @param[in] string $LSobject Le type de l'objet * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut) * @param[in] string $right Le type de droit d'accès à tester ('r'/'w') * @param[in] string $attr Le nom de l'attribut auquel on test l'accès * * @retval boolean True si l'utilisateur a accès, false sinon */ public static function canAccess($LSobject,$dn=NULL,$right=NULL,$attr=NULL) { if (!self :: loadLSobject($LSobject)) { return; } if ($dn) { $whoami = self :: whoami($dn); if ($dn==self :: getLSuserObject() -> getValue('dn')) { if (!self :: in_menu('SELF')) { return; } } else { $obj = new $LSobject(); $obj -> dn = $dn; if (!self :: in_menu($LSobject,$obj -> subDnValue)) { return; } } } else { $objectdn=LSconfig :: get('LSobjects.'.$LSobject.'.container_dn').','.self :: $topDn; $whoami = self :: whoami($objectdn); } // Pour un attribut particulier if ($attr) { if ($attr=='rdn') { $attr=LSconfig :: get('LSobjects.'.$LSobject.'.rdn'); } if (!is_array(LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr))) { return; } $r = 'n'; foreach($whoami as $who) { $nr = LSconfig :: get('LSobjects.'.$LSobject.'.attrs.'.$attr.'.rights.'.$who); if($nr == 'w') { $r = 'w'; } else if($nr == 'r') { if ($r=='n') { $r='r'; } } } if (($right=='r')||($right=='w')) { if ($r==$right) { return true; } return; } else { if ( ($r=='r') || ($r=='w') ) { return true; } return; } } // Pour un attribut quelconque $attrs_conf=LSconfig :: get('LSobjects.'.$LSobject.'.attrs'); if (is_array($attrs_conf)) { if (($right=='r')||($right=='w')) { foreach($whoami as $who) { foreach ($attrs_conf as $attr_name => $attr_config) { if ($attr_config['rights'][$who]==$right) { return true; } } } } else { foreach($whoami as $who) { foreach ($attrs_conf as $attr_name => $attr_config) { if ( ($attr_config['rights'][$who]=='r') || ($attr_config['rights'][$who]=='w') ) { return true; } } } } } return; } /** * Retourne le droit de l'utilisateur à editer à un objet * * @param[in] string $LSobject Le type de l'objet * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut) * @param[in] string $attr Le nom de l'attribut auquel on test l'accès * * @retval boolean True si l'utilisateur a accès, false sinon */ public static function canEdit($LSobject,$dn=NULL,$attr=NULL) { return self :: canAccess($LSobject,$dn,'w',$attr); } /** * Retourne le droit de l'utilisateur à supprimer un objet * * @param[in] string $LSobject Le type de l'objet * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut) * * @retval boolean True si l'utilisateur a accès, false sinon */ public static function canRemove($LSobject,$dn) { return self :: canAccess($LSobject,$dn,'w','rdn'); } /** * Retourne le droit de l'utilisateur à créer un objet * * @param[in] string $LSobject Le type de l'objet * * @retval boolean True si l'utilisateur a accès, false sinon */ public static function canCreate($LSobject) { if (!self :: loadLSobject($LSobject)) { return; } if (LSconfig :: get("LSobjects.$LSobject.disable_creation")) { return; } return self :: canAccess($LSobject,NULL,'w','rdn'); } /** * Retourne le droit de l'utilisateur à gérer la relation d'objet * * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut) * @param[in] string $LSobject Le type de l'objet * @param[in] string $relationName Le nom de la relation avec l'objet * @param[in] string $right Le type de droit a vérifier ('r' ou 'w') * * @retval boolean True si l'utilisateur a accès, false sinon */ public static function relationCanAccess($dn,$LSobject,$relationName,$right=NULL) { $relConf=LSconfig :: get('LSobjects.'.$LSobject.'.LSrelation.'.$relationName); if (!is_array($relConf)) return; $whoami = self :: whoami($dn); if (($right=='w') || ($right=='r')) { $r = 'n'; foreach($whoami as $who) { $nr = $relConf['rights'][$who]; if($nr == 'w') { $r = 'w'; } else if($nr == 'r') { if ($r=='n') { $r='r'; } } } if ($r == $right) { return true; } } else { foreach($whoami as $who) { if (($relConf['rights'][$who] == 'w') || ($relConf['rights'][$who] == 'r')) { return true; } } } return; } /** * Retourne le droit de l'utilisateur à modifier la relation d'objet * * @param[in] string $dn Le DN de l'objet (le container_dn du type de l'objet par défaut) * @param[in] string $LSobject Le type de l'objet * @param[in] string $relationName Le nom de la relation avec l'objet * * @retval boolean True si l'utilisateur a accès, false sinon */ public static function relationCanEdit($dn,$LSobject,$relationName) { return self :: relationCanAccess($dn,$LSobject,$relationName,'w'); } /** * Ajoute un fichier temporaire * * @author Benjamin Renard * * @retval void **/ public static function addTmpFile($value,$filePath) { $hash = mhash(MHASH_MD5,$value); self :: $tmp_file[$filePath] = $hash; $_SESSION['LSsession']['tmp_file'][$filePath] = $hash; } /** * Retourne le chemin du fichier temporaire si l'existe * * @author Benjamin Renard * * @param[in] $value La valeur du fichier * * @retval mixed **/ public static function tmpFileExist($value) { $hash = mhash(MHASH_MD5,$value); foreach(self :: $tmp_file as $filePath => $contentHash) { if ($hash == $contentHash) { return $filePath; } } return false; } /** * Retourne le chemin du fichier temporaire * * Retourne le chemin du fichier temporaire qu'il créera à partir de la valeur * s'il n'existe pas déjà. * * @author Benjamin Renard * * @param[in] $value La valeur du fichier * * @retval mixed **/ public static function getTmpFile($value) { $exist = self :: tmpFileExist($value); if (!$exist) { $img_path = LS_TMP_DIR .rand().'.tmp'; $fp = fopen($img_path, "w"); fwrite($fp, $value); fclose($fp); self :: addTmpFile($value,$img_path); return $img_path; } else { return $exist; } } /** * Supprime les fichiers temporaires * * @author Benjamin Renard * * @retval void **/ public static function deleteTmpFile($filePath=NULL) { if ($filePath) { @unlink($filePath); unset(self :: $tmp_file[$filePath]); unset($_SESSION['LSsession']['tmp_file'][$filePath]); } else { foreach(self :: $tmp_file as $file => $content) { @unlink($file); } self :: $tmp_file = array(); $_SESSION['LSsession']['tmp_file'] = array(); } } /** * Retourne true si le cache des droits est activé * * @author Benjamin Renard * * @retval boolean True si le cache des droits est activé, false sinon. */ public static function cacheLSprofiles() { return ( (LSconfig :: get('cacheLSprofiles')) || (self :: $ldapServer['cacheLSprofiles']) ); } /** * Retourne true si le cache des subDn est activé * * @author Benjamin Renard * * @retval boolean True si le cache des subDn est activé, false sinon. */ public static function cacheSudDn() { return ( (LSconfig :: get('cacheSubDn')) || (self :: $ldapServer['cacheSubDn'])); } /** * Retourne true si le cache des recherches est activé * * @author Benjamin Renard * * @retval boolean True si le cache des recherches est activé, false sinon. */ public static function cacheSearch() { return ( (LSconfig :: get('cacheSearch')) || (self :: $ldapServer['cacheSearch'])); } /** * Retourne le label des niveaux pour le serveur ldap courant * * @author Benjamin Renard * * @retval string Le label des niveaux pour le serveur ldap dourant */ public static function getSubDnLabel() { return (self :: $ldapServer['subDnLabel']!='')?__(self :: $ldapServer['subDnLabel']):_('Level'); } /** * Retourne le nom du subDn * * @param[in] $subDn string subDn * * @retval string Le nom du subDn ou '' sinon */ public static function getSubDnName($subDn=false) { if (!$subDn) { $subDn = self :: $topDn; } if (self :: getSubDnLdapServer()) { if (isset(self :: $_subDnLdapServer[self :: $ldapServerId][$subDn])) { return self :: $_subDnLdapServer[self :: $ldapServerId][$subDn]; } } return ''; } /** * L'objet est t-il utilisé pour listé les subDnS * * @param[in] $type string Le type d'objet * * @retval boolean true si le type d'objet est un subDnObject, false sinon */ public static function isSubDnLSobject($type) { $result = false; if (is_array(self :: $ldapServer['subDn']['LSobject'])) { foreach(self :: $ldapServer['subDn']['LSobject'] as $key => $value) { if ($key==$type) { $result=true; } } } return $result; } /** * Indique si un type d'objet est dans le menu courant * * @retval boolean true si le type d'objet est dans le menu, false sinon */ public static function in_menu($LSobject,$topDn=NULL) { if (!$topDn) { $topDn=self :: $topDn; } return isset(self :: $LSaccess[$topDn][$LSobject]); } /** * Indique si le serveur LDAP courant a des subDn * * @retval boolean true si le serveur LDAP courant a des subDn, false sinon */ public static function haveSubDn() { return (isset(self :: $ldapServer['subDn']) && is_array(self :: $ldapServer['subDn'])); } /** * Ajoute une information à afficher * * @param[in] $msg string Le message à afficher * * @retval void */ public static function addInfo($msg) { $_SESSION['LSsession_infos'][]=$msg; } /** * Redirection de l'utilisateur vers une autre URL * * @param[in] $url string L'URL * @param[in] $exit boolean Si true, l'execution script s'arrête après la redirection * * @retval void */ public static function redirect($url,$exit=true) { $GLOBALS['Smarty'] -> assign('url',$url); $GLOBALS['Smarty'] -> display('redirect.tpl'); if ($exit) { exit(); } } /** * Retourne l'adresse mail d'emission configurée pour le serveur courant * * @retval string Adresse mail d'emission */ public static function getEmailSender() { return self :: $ldapServer['emailSender']; } /** * Ajout d'une information d'aide * * @param[in] $group string Le nom du groupe d'infos dans lequels ajouter * celle-ci * @param[in] $infos array Tableau array(name => value) des infos * * @retval void */ public static function addHelpInfos($group,$infos) { if (is_array($infos)) { if (is_array(self :: $_JSconfigParams['helpInfos'][$group])) { self :: $_JSconfigParams['helpInfos'][$group] = array_merge(self :: $_JSconfigParams['helpInfos'][$group],$infos); } else { self :: $_JSconfigParams['helpInfos'][$group] = $infos; } } } /** * Défini les codes erreur relative à la classe LSsession * * @retval void */ private static function defineLSerrors() { /* * Error Codes */ LSerror :: defineError('LSsession_01', _("LSsession : The constant %{const} is not defined.") ); LSerror :: defineError('LSsession_02', _("LSsession : The %{addon} support is uncertain. Verify system compatibility and the add-on configuration.") ); LSerror :: defineError('LSsession_03', _("LSsession : LDAP server's configuration data are invalid. Can't connect.") ); LSerror :: defineError('LSsession_04', _("LSsession : Failed to load LSobject type %{type} : unknon type.") ); LSerror :: defineError('LSsession_05', _("LSsession : Failed to load LSclass %{class}.") ); LSerror :: defineError('LSsession_06', _("LSsession : Login or password incorrect.") ); LSerror :: defineError('LSsession_07', _("LSsession : Impossible to identify you : Duplication of identities.") ); LSerror :: defineError('LSsession_08', _("LSsession : Can't load class of authentification (%{class}).") ); LSerror :: defineError('LSsession_09', _("LSsession : Can't connect to LDAP server.") ); LSerror :: defineError('LSsession_10', _("LSsession : Impossible to authenticate you.") ); LSerror :: defineError('LSsession_11', _("LSsession : Your are not authorized to do this action.") ); LSerror :: defineError('LSsession_12', _("LSsession : Some informations are missing to display this page.") ); // 13 -> 16 : not yet used LSerror :: defineError('LSsession_17', _("LSsession : Error during creation of list of levels. Contact administrators. (Code : %{code})") ); LSerror :: defineError('LSsession_18', _("LSsession : The password recovery is disabled for this LDAP server.") ); LSerror :: defineError('LSsession_19', _("LSsession : Some informations are missing to recover your password. Contact administrators.") ); LSerror :: defineError('LSsession_20', _("LSsession : Error during password recovery. Contact administrators.(Step : %{step})") ); // 21 : not yet used LSerror :: defineError('LSsession_22', _("LSsession : problem during initialisation.") ); } /** * Ajax method when change ldapserver on login form * * @param[in] $data array The return data address * * @retval void **/ public static function ajax_onLdapServerChangedLogin(&$data) { if ( isset($_REQUEST['server']) ) { self :: setLdapServer($_REQUEST['server']); $data = array(); if ( self :: LSldapConnect() ) { session_start(); if (isset($_SESSION['LSsession_topDn'])) { $sel = $_SESSION['LSsession_topDn']; } else { $sel = NULL; } $list = self :: getSubDnLdapServerOptions($sel); if (is_string($list)) { $data['list_topDn'] = ""; $data['subDnLabel'] = self :: getSubDnLabel(); } } $data['recoverPassword'] = isset(self :: $ldapServer['recoverPassword']); } } /** * Ajax method when change ldapserver on recoverPassword form * * @param[in] $data array The return data address * * @retval void **/ public static function ajax_onLdapServerChangedRecoverPassword(&$data) { if ( isset($_REQUEST['server']) ) { self :: setLdapServer($_REQUEST['server']); $data=array('recoverPassword' => isset(self :: $ldapServer['recoverPassword'])); } } } ?>