diff --git a/htdocs/adherents/adherent.class.php b/htdocs/adherents/adherent.class.php index 96c99a03b52..e79b0e790d4 100644 --- a/htdocs/adherents/adherent.class.php +++ b/htdocs/adherents/adherent.class.php @@ -346,7 +346,7 @@ class Adherent extends CommonObject $nbrowsaffected=0; $error=0; - dolibarr_syslog("Adherent::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser); + dolibarr_syslog("Adherent::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", email=".$this->email); // Verification parametres if ($conf->global->ADHERENT_MAIL_REQUIRED && ! ValidEMail($this->email)) diff --git a/htdocs/adherents/fiche.php b/htdocs/adherents/fiche.php index 4585b879574..d26125aaa08 100644 --- a/htdocs/adherents/fiche.php +++ b/htdocs/adherents/fiche.php @@ -125,26 +125,26 @@ if ($_REQUEST["action"] == 'update' && ! $_POST["cancel"]) if ($result > 0) { // Modifie valeures - $adh->prenom = $_POST["prenom"]; - $adh->nom = $_POST["nom"]; + $adh->prenom = trim($_POST["prenom"]); + $adh->nom = trim($_POST["nom"]); $adh->fullname = trim($adh->prenom.' '.$adh->nom); - $adh->login = $_POST["login"]; - $adh->pass = $_POST["pass"]; + $adh->login = trim($_POST["login"]); + $adh->pass = trim($_POST["pass"]); - $adh->societe = $_POST["societe"]; - $adh->adresse = $_POST["adresse"]; - $adh->cp = $_POST["cp"]; - $adh->ville = $_POST["ville"]; + $adh->societe = trim($_POST["societe"]); + $adh->adresse = trim($_POST["adresse"]); + $adh->cp = trim($_POST["cp"]); + $adh->ville = trim($_POST["ville"]); $adh->pays_id = $_POST["pays"]; - $adh->phone = $_POST["phone"]; - $adh->phone_perso = $_POST["phone_perso"]; - $adh->phone_mobile= $_POST["phone_mobile"]; - $adh->email = $_POST["email"]; + $adh->phone = trim($_POST["phone"]); + $adh->phone_perso = trim($_POST["phone_perso"]); + $adh->phone_mobile= trim($_POST["phone_mobile"]); + $adh->email = trim($_POST["email"]); $adh->naiss = $datenaiss; $adh->typeid = $_POST["type"]; - $adh->note = $_POST["comment"]; + $adh->note = trim($_POST["comment"]); $adh->morphy = $_POST["morphy"]; $adh->amount = $_POST["amount"]; diff --git a/htdocs/admin/ldap_contacts.php b/htdocs/admin/ldap_contacts.php index 52ced4610c9..13038b29299 100644 --- a/htdocs/admin/ldap_contacts.php +++ b/htdocs/admin/ldap_contacts.php @@ -50,6 +50,7 @@ if ($_GET["action"] == 'setvalue' && $user->admin) if (! dolibarr_set_const($db, 'LDAP_CONTACT_DN',$_POST["contactdn"])) $error++; if (! dolibarr_set_const($db, 'LDAP_CONTACT_OBJECT_CLASS',$_POST["objectclass"])) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_FULLNAME',$_POST["fieldfullname"])) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_NAME',$_POST["fieldname"])) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_FIRSTNAME',$_POST["fieldfirstname"])) $error++; @@ -252,17 +253,13 @@ print info_admin($langs->trans("LDAPDescValues")); /* * Test de la connexion */ -print '
'; -if (! function_exists("ldap_connect")) -{ - print ''.$langs->trans("LDAPTestSynchroContact").''; -} -else if (empty($conf->global->LDAP_SERVER_HOST)) -{ - print ''.$langs->trans("LDAPTestSynchroContact").''; -} -else print ''.$langs->trans("LDAPTestSynchroContact").''; -print '

'; +$butlabel=$langs->trans("LDAPTestSynchroContact"); +$testlabel='test'; +$key=$conf->global->LDAP_KEY_CONTACTS; +$dn=$conf->global->LDAP_CONTACT_DN; +$objectclass=$conf->global->LDAP_CONTACT_OBJECT_CLASS; + +show_ldap_test_button($butlabel,$testlabel,$key,$dn,$objectclass); if (function_exists("ldap_connect")) @@ -270,8 +267,8 @@ if (function_exists("ldap_connect")) if ($_GET["action"] == 'test') { // Creation objet - $contact=new Contact($db); - $contact->initAsSpecimen(); + $object=new Contact($db); + $object->initAsSpecimen(); // Test synchro $ldap=new Ldap(); @@ -279,8 +276,8 @@ if (function_exists("ldap_connect")) if ($result > 0) { - $info=$contact->_load_ldap_info(); - $dn=$contact->_load_ldap_dn($info); + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); $result2=$ldap->update($dn,$info,$user); $result3=$ldap->delete($dn); @@ -296,6 +293,7 @@ if (function_exists("ldap_connect")) print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); print ': '.$ldap->error; print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; } } else @@ -304,8 +302,13 @@ if (function_exists("ldap_connect")) print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; } + print "
\n"; + print "LDAP input file used for test:

\n"; + print nl2br($ldap->dump_content($dn,$info)); + print "\n
"; } } diff --git a/htdocs/admin/ldap_groups.php b/htdocs/admin/ldap_groups.php index d3b80da4710..30f0d5c3e09 100644 --- a/htdocs/admin/ldap_groups.php +++ b/htdocs/admin/ldap_groups.php @@ -51,6 +51,7 @@ if ($_GET["action"] == 'setvalue' && $user->admin) if (! dolibarr_set_const($db, 'LDAP_GROUP_DN',$_POST["group"])) $error++; if (! dolibarr_set_const($db, 'LDAP_GROUP_OBJECT_CLASS',$_POST["objectclass"])) $error++; + if (! dolibarr_set_const($db, 'LDAP_FIELD_FULLNAME',$_POST["fieldfullname"])) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_NAME',$_POST["fieldname"])) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_DESCRIPTION',$_POST["fielddescription"])) $error++; @@ -172,19 +173,15 @@ print info_admin($langs->trans("LDAPDescValues")); /* * Test de la connexion */ -print '
'; if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { - if (! function_exists("ldap_connect")) - { - print ''.$langs->trans("LDAPTestSynchroGroup").''; - } - else if (empty($conf->global->LDAP_SERVER_HOST)) - { - print ''.$langs->trans("LDAPTestSynchroGroup").''; - } - else print ''.$langs->trans("LDAPTestSynchroGroup").''; - print '

'; + $butlabel=$langs->trans("LDAPTestSynchroGroup"); + $testlabel='testgroup'; + $key=$conf->global->LDAP_KEY_GROUPS; + $dn=$conf->global->LDAP_GROUP_DN; + $objectclass=$conf->global->LDAP_GROUP_OBJECT_CLASS; + + show_ldap_test_button($butlabel,$testlabel,$key,$dn,$objectclass); } if (function_exists("ldap_connect")) @@ -192,8 +189,8 @@ if (function_exists("ldap_connect")) if ($_GET["action"] == 'testgroup') { // Creation objet - $fgroup=new UserGroup($db); - $fgroup->initAsSpecimen(); + $object=new UserGroup($db); + $object->initAsSpecimen(); // Test synchro $ldap=new Ldap(); @@ -201,8 +198,8 @@ if (function_exists("ldap_connect")) if ($result > 0) { - $info=$fgroup->_load_ldap_info(); - $dn=$fgroup->_load_ldap_dn($info); + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); $result2=$ldap->update($dn,$info,$user); $result3=$ldap->delete($dn); @@ -218,6 +215,7 @@ if (function_exists("ldap_connect")) print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); print ': '.$ldap->error; print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; } } else @@ -226,12 +224,17 @@ if (function_exists("ldap_connect")) print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; } + + print "
\n"; + print "LDAP input file used for test:

\n"; + print nl2br($ldap->dump_content($dn,$info)); + print "\n
"; } } $db->close(); llxFooter('$Date$ - $Revision$'); - ?> diff --git a/htdocs/admin/ldap_members.php b/htdocs/admin/ldap_members.php index e3462f30a30..7c2362a05e5 100644 --- a/htdocs/admin/ldap_members.php +++ b/htdocs/admin/ldap_members.php @@ -48,6 +48,7 @@ if ($_GET["action"] == 'setvalue' && $user->admin) { $error=0; if (! dolibarr_set_const($db, 'LDAP_KEY_MEMBERS',$_POST["key"])) $error++; + if (! dolibarr_set_const($db, 'LDAP_MEMBER_DN',$_POST["user"])) $error++; if (! dolibarr_set_const($db, 'LDAP_MEMBER_OBJECT_CLASS',$_POST["objectclass"])) $error++; // Members @@ -366,17 +367,13 @@ print info_admin($langs->trans("LDAPDescValues")); */ if ($conf->global->LDAP_MEMBER_ACTIVE) { - print '
'; - if (! function_exists("ldap_connect")) - { - print ''.$langs->trans("LDAPTestSynchroMember").''; - } - else if (empty($conf->global->LDAP_SERVER_HOST)) - { - print ''.$langs->trans("LDAPTestSynchroMember").''; - } - else print ''.$langs->trans("LDAPTestSynchroMember").''; - print '

'; + $butlabel=$langs->trans("LDAPTestSynchroMember"); + $testlabel='testmember'; + $key=$conf->global->LDAP_KEY_MEMBERS; + $dn=$conf->global->LDAP_MEMBER_DN; + $objectclass=$conf->global->LDAP_MEMBER_OBJECT_CLASS; + + show_ldap_test_button($butlabel,$testlabel,$key,$dn,$objectclass); } if (function_exists("ldap_connect")) @@ -384,8 +381,8 @@ if (function_exists("ldap_connect")) if ($_GET["action"] == 'testmember') { // Creation objet - $adherent=new Adherent($db); - $adherent->initAsSpecimen(); + $object=new Adherent($db); + $object->initAsSpecimen(); // Test synchro $ldap=new Ldap(); @@ -393,8 +390,8 @@ if (function_exists("ldap_connect")) if ($result > 0) { - $info=$adherent->_load_ldap_info(); - $dn=$adherent->_load_ldap_dn($info); + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); $result2=$ldap->update($dn,$info,$user); $result3=$ldap->delete($dn); @@ -410,6 +407,7 @@ if (function_exists("ldap_connect")) print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); print ': '.$ldap->error; print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; } } else @@ -418,6 +416,7 @@ if (function_exists("ldap_connect")) print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; } print "
\n"; diff --git a/htdocs/admin/ldap_users.php b/htdocs/admin/ldap_users.php index be8796eb834..e9b068f46b6 100644 --- a/htdocs/admin/ldap_users.php +++ b/htdocs/admin/ldap_users.php @@ -51,6 +51,7 @@ if ($_GET["action"] == 'setvalue' && $user->admin) if (! dolibarr_set_const($db, 'LDAP_USER_DN',$_POST["user"])) $error++; if (! dolibarr_set_const($db, 'LDAP_USER_OBJECT_CLASS',$_POST["objectclass"])) $error++; + if (! dolibarr_set_const($db, 'LDAP_FILTER_CONNECTION',$_POST["filterconnection"])) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_FULLNAME',$_POST["fieldfullname"])) $error++; if (! dolibarr_set_const($db, 'LDAP_FIELD_LOGIN',$_POST["fieldlogin"])) $error++; @@ -266,17 +267,13 @@ print info_admin($langs->trans("LDAPDescValues")); */ if ($conf->global->LDAP_SYNCHRO_ACTIVE == 'dolibarr2ldap') { - print '
'; - if (! function_exists("ldap_connect")) - { - print ''.$langs->trans("LDAPTestSynchroUser").''; - } - else if (empty($conf->global->LDAP_SERVER_HOST)) - { - print ''.$langs->trans("LDAPTestSynchroUser").''; - } - else print ''.$langs->trans("LDAPTestSynchroUser").''; - print '

'; + $butlabel=$langs->trans("LDAPTestSynchroUser"); + $testlabel='testuser'; + $key=$conf->global->LDAP_KEY_USERS; + $dn=$conf->global->LDAP_USER_DN; + $objectclass=$conf->global->LDAP_USER_OBJECT_CLASS; + + show_ldap_test_button($butlabel,$testlabel,$key,$dn,$objectclass); } if (function_exists("ldap_connect")) @@ -284,17 +281,19 @@ if (function_exists("ldap_connect")) if ($_GET["action"] == 'testuser') { // Creation objet - $fuser=new User($db); - $fuser->initAsSpecimen(); + $object=new User($db); + $object->initAsSpecimen(); + // TODO Mutualize code following with other ldap_xxxx.php pages + // Test synchro $ldap=new Ldap(); $result=$ldap->connect_bind(); if ($result > 0) { - $info=$fuser->_load_ldap_info(); - $dn=$fuser->_load_ldap_dn($info); + $info=$object->_load_ldap_info(); + $dn=$object->_load_ldap_dn($info); $result2=$ldap->update($dn,$info,$user); $result3=$ldap->delete($dn); @@ -310,6 +309,7 @@ if (function_exists("ldap_connect")) print ''.$langs->trans("LDAPSynchroKOMayBePermissions"); print ': '.$ldap->error; print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; } } else @@ -318,8 +318,13 @@ if (function_exists("ldap_connect")) print ''.$langs->trans("LDAPSynchroKO"); print ': '.$ldap->error; print '
'; + print $langs->trans("ErrorLDAPMakeManualTest",$conf->ldap->dir_temp).'
'; } + print "
\n"; + print "LDAP input file used for test:

\n"; + print nl2br($ldap->dump_content($dn,$info)); + print "\n
"; } } @@ -327,5 +332,4 @@ if (function_exists("ldap_connect")) $db->close(); llxFooter('$Date$ - $Revision$'); - ?> diff --git a/htdocs/conf/conf.class.php b/htdocs/conf/conf.class.php index a0f3212e480..bb2b13b73fb 100644 --- a/htdocs/conf/conf.class.php +++ b/htdocs/conf/conf.class.php @@ -38,18 +38,19 @@ class Conf { /** \public */ //! Object with database handler - var $db; - //! Charset for HTML output - var $character_set_client; // UTF8, ISO-8859-1 + var $db; + + //! Charset for HTML output and for storing data in memory + var $character_set_client='UTF-8'; // UTF-8, ISO-8859-1 var $dol_document_root; - + var $monnaie; // Used to store current currency var $css; // Used to store current css (from theme) - + var $css_modules=array(); var $tabs_modules=array(); - + /** * \brief Positionne toutes les variables de configuration diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index e1533eb615f..0849f98e887 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -36,4 +36,6 @@ WarningBuildScriptNotRunned=Script %s was not yet ran to build graphics, WarningBookmarkAlreadyExists=A bookmark with this title or this target (URL) already exists. WarningPassIsEmpty=Warning, database password is empty. This is a security hole. You should add a password to your database and change your conf.php file to reflect this. ErrorNoAccountancyModuleLoaded=No accountancy module activated -ErrorExportDuplicateProfil=This profil name already exists for this export set. \ No newline at end of file +ErrorExportDuplicateProfil=This profil name already exists for this export set. +ErrorLDAPSetupNotComplete=Dolibarr-LDAP matching is not complete. +ErrorLDAPMakeManualTest=A .ldif file has been generated in directory %s. Try to load it manually from command line to have more informations on errors. diff --git a/htdocs/langs/fr_FR/errors.lang b/htdocs/langs/fr_FR/errors.lang index fcf58f2948f..21c11550b60 100644 --- a/htdocs/langs/fr_FR/errors.lang +++ b/htdocs/langs/fr_FR/errors.lang @@ -37,3 +37,5 @@ WarningBookmarkAlreadyExists=Un marque-page avec ce titre ou cette destination ( WarningPassIsEmpty=Attention, le mot de passe de la base de donnée Dolibarr est vide. Cela représente une faille de sécurité. Il est recommandé d'ajouter manuellement un mot de passe à la base et de modifier le fichier conf.php pour refléter ce changement. ErrorNoAccountancyModuleLoaded=Aucun module de comptabilité activé ErrorExportDuplicateProfil=Ce nom de profil existe déjà pour ce lot d'export. +ErrorLDAPSetupNotComplete=Le matching Dolibarr-LDAP est incomplet. +ErrorLDAPMakeManualTest=Un fichier .ldif a été généré dans le répertoire %s. Essayer de charger ce fichier en manuel depuis la ligne de commande pour plus de détail sur l'erreur. \ No newline at end of file diff --git a/htdocs/lib/admin.lib.php b/htdocs/lib/admin.lib.php index 9eb15332dbb..97928cfd363 100644 --- a/htdocs/lib/admin.lib.php +++ b/htdocs/lib/admin.lib.php @@ -419,5 +419,4 @@ function security_prepare_head() return $head; } - ?> \ No newline at end of file diff --git a/htdocs/lib/functions.lib.php b/htdocs/lib/functions.lib.php index d0d6b8d50fb..591904d0498 100644 --- a/htdocs/lib/functions.lib.php +++ b/htdocs/lib/functions.lib.php @@ -44,10 +44,10 @@ if (! defined('ADODB_DATE_VERSION')) include_once(DOL_DOCUMENT_ROOT."/includes/a */ function ValidEmail($address) { - if (ereg( ".*<(.+)>", $address, $regs)) { + if (eregi(".*<(.+)>", $address, $regs)) { $address = $regs[1]; } - if (ereg( "^[^@ ]+@([a-zA-Z0-9\-]+\.)+([a-zA-Z0-9\-]{2}|coop|aero|biz|com|edu|gov|info|int|mil|name|net|org)\$",$address)) + if (eregi("^[^@ ]+@([a-zA-Z0-9\-]+\.)+([a-zA-Z0-9\-]{2}|coop|aero|biz|com|edu|gov|info|int|mil|name|net|org)\$",$address)) { return true; } diff --git a/htdocs/lib/ldap.class.php b/htdocs/lib/ldap.class.php index 973969bf3da..824d0128d26 100644 --- a/htdocs/lib/ldap.class.php +++ b/htdocs/lib/ldap.class.php @@ -20,131 +20,132 @@ * or see http://www.gnu.org/ */ - /** - \file htdocs/lib/ldap.class.php - \brief Classe de gestion d'annuaire LDAP - \author Rodolphe Quiedeville - \author Benoit Mortier - \author Regis Houssin - \author Laurent Destailleur - \version $Id$ -*/ + * \file htdocs/lib/ldap.class.php + * \brief Classe de gestion d'annuaire LDAP + * \author Rodolphe Quiedeville + * \author Benoit Mortier + * \author Regis Houssin + * \author Laurent Destailleur + * \version $Id$ + */ class Ldap { - /** - * Tableau des serveurs (IP addresses ou nom d'hôtes) - */ - var $server=array(); - /** - * Base DN (e.g. "dc=foo,dc=com") - */ - var $dn; - /** - * type de serveur, actuellement OpenLdap et Active Directory - */ - var $serverType; - /** - * Version du protocole ldap - */ - var $domain; - /** - * User administrateur Ldap - * Active Directory ne supporte pas les connexions anonymes - */ - var $searchUser; - /** - * Mot de passe de l'administrateur - * Active Directory ne supporte pas les connexions anonymes - */ - var $searchPassword; - /** - * DN des utilisateurs - */ - var $people; - /** - * DN des groupes - */ - var $groups; - /** - * Code erreur retourné par le serveur Ldap - */ - var $ldapErrorCode; - /** - * Message texte de l'erreur - */ - var $ldapErrorText; + /** + * Tableau des serveurs (IP addresses ou nom d'hôtes) + */ + var $server=array(); + /** + * Base DN (e.g. "dc=foo,dc=com") + */ + var $dn; + /** + * type de serveur, actuellement OpenLdap et Active Directory + */ + var $serverType; + /** + * Version du protocole ldap + */ + var $domain; + /** + * User administrateur Ldap + * Active Directory ne supporte pas les connexions anonymes + */ + var $searchUser; + /** + * Mot de passe de l'administrateur + * Active Directory ne supporte pas les connexions anonymes + */ + var $searchPassword; + /** + * DN des utilisateurs + */ + var $people; + /** + * DN des groupes + */ + var $groups; + /** + * Code erreur retourné par le serveur Ldap + */ + var $ldapErrorCode; + /** + * Message texte de l'erreur + */ + var $ldapErrorText; - //Fetch user - var $name; - var $firstname; - var $login; - var $phone; - var $fax; - var $mail; - var $mobile; + //Fetch user + var $name; + var $firstname; + var $login; + var $phone; + var $fax; + var $mail; + var $mobile; - var $uacf; - var $pwdlastset; + var $uacf; + var $pwdlastset; + + var $ldapcharset='UTF-8'; // LDAP should be UTF-8 encoded - // 1.2 Private properties ---------------------------------------------------- - /** - * The internal LDAP connection handle - */ - var $connection; - /** - * Result of any connections etc. - */ - var $result; + // 1.2 Private properties ---------------------------------------------------- + /** + * The internal LDAP connection handle + */ + var $connection; + /** + * Result of any connections etc. + */ + var $result; - /** - * Constructor- creates a new instance of the authentication class - * - */ - function Ldap () - { - global $conf; + /** + * Constructor- creates a new instance of the authentication class + * + */ + function Ldap () + { + global $conf; - //Server - if ($conf->global->LDAP_SERVER_HOST) $this->server[] = $conf->global->LDAP_SERVER_HOST; - if ($conf->global->LDAP_SERVER_HOST_SLAVE) $this->server[] = $conf->global->LDAP_SERVER_HOST_SLAVE; - $this->serverPort = $conf->global->LDAP_SERVER_PORT; - $this->ldapProtocolVersion = $conf->global->LDAP_SERVER_PROTOCOLVERSION; - $this->dn = $conf->global->LDAP_SERVER_DN; - $this->serverType = $conf->global->LDAP_SERVER_TYPE; - $this->domain = $conf->global->LDAP_SERVER_DN; - $this->searchUser = $conf->global->LDAP_ADMIN_DN; - $this->searchPassword = $conf->global->LDAP_ADMIN_PASS; - $this->people = $conf->global->LDAP_USER_DN; - $this->groups = $conf->global->LDAP_GROUP_DN; - $this->filter = $conf->global->LDAP_FILTER_CONNECTION; + //Server + if ($conf->global->LDAP_SERVER_HOST) $this->server[] = $conf->global->LDAP_SERVER_HOST; + if ($conf->global->LDAP_SERVER_HOST_SLAVE) $this->server[] = $conf->global->LDAP_SERVER_HOST_SLAVE; + $this->serverPort = $conf->global->LDAP_SERVER_PORT; + $this->ldapProtocolVersion = $conf->global->LDAP_SERVER_PROTOCOLVERSION; + $this->dn = $conf->global->LDAP_SERVER_DN; + $this->serverType = $conf->global->LDAP_SERVER_TYPE; + $this->domain = $conf->global->LDAP_SERVER_DN; + $this->searchUser = $conf->global->LDAP_ADMIN_DN; + $this->searchPassword = $conf->global->LDAP_ADMIN_PASS; + $this->people = $conf->global->LDAP_USER_DN; + $this->groups = $conf->global->LDAP_GROUP_DN; + $this->filter = $conf->global->LDAP_FILTER_CONNECTION; - //Users - $this->attr_login = $conf->global->LDAP_FIELD_LOGIN; //unix - $this->attr_sambalogin = $conf->global->LDAP_FIELD_LOGIN_SAMBA; //samba, activedirectory - $this->attr_name = $conf->global->LDAP_FIELD_NAME; - $this->attr_firstname = $conf->global->LDAP_FIELD_FIRSTNAME; - $this->attr_mail = $conf->global->LDAP_FIELD_MAIL; - $this->attr_phone = $conf->global->LDAP_FIELD_PHONE; - $this->attr_fax = $conf->global->LDAP_FIELD_FAX; - $this->attr_mobile = $conf->global->LDAP_FIELD_MOBILE; - } + //Users + $this->attr_login = $conf->global->LDAP_FIELD_LOGIN; //unix + $this->attr_sambalogin = $conf->global->LDAP_FIELD_LOGIN_SAMBA; //samba, activedirectory + $this->attr_name = $conf->global->LDAP_FIELD_NAME; + $this->attr_firstname = $conf->global->LDAP_FIELD_FIRSTNAME; + $this->attr_mail = $conf->global->LDAP_FIELD_MAIL; + $this->attr_phone = $conf->global->LDAP_FIELD_PHONE; + $this->attr_fax = $conf->global->LDAP_FIELD_FAX; + $this->attr_mobile = $conf->global->LDAP_FIELD_MOBILE; + } - // 2.1 Connection handling methods ------------------------------------------- + // 2.1 Connection handling methods ------------------------------------------- - /** - * 2.1.1 : Connects to the server. Just creates a connection which is used - * in all later access to the LDAP server. If it can't connect and bind - * anonymously, it creates an error code of -1. Returns true if connected, - * false if failed. Takes an array of possible servers - if one doesn't work, - * it tries the next and so on. - * \deprecated Utiliser connect_bind a la place - */ + /** + * 2.1.1 : Connects to the server. Just creates a connection which is used + * in all later access to the LDAP server. If it can't connect and bind + * anonymously, it creates an error code of -1. Returns true if connected, + * false if failed. Takes an array of possible servers - if one doesn't work, + * it tries the next and so on. + * \deprecated Utiliser connect_bind a la place + */ function connect() { foreach ($this->server as $key => $host) @@ -180,12 +181,12 @@ class Ldap } - /** - * \brief Connect and bind - * \return <0 si KO, 1 si bind anonymous, 2 si bind auth - * \remarks Use this->server, this->serverPort, this->ldapProtocolVersion, this->serverType, this->searchUser, this->searchPassword - * After return, this->connection and $this->bind are defined - */ + /** + * \brief Connect and bind + * \return <0 si KO, 1 si bind anonymous, 2 si bind auth + * \remarks Use this->server, this->serverPort, this->ldapProtocolVersion, this->serverType, this->searchUser, this->searchPassword + * After return, this->connection and $this->bind are defined + */ function connect_bind() { global $langs; @@ -282,67 +283,67 @@ class Ldap - /** - * 2.1.2 : Simply closes the connection set up earlier. - * Returns true if OK, false if there was an error. - */ - function close() - { - if ($this->connection && ! @ldap_close($this->connection)) - { - return false; - } - else - { - return true; - } - } + /** + * 2.1.2 : Simply closes the connection set up earlier. + * Returns true if OK, false if there was an error. + */ + function close() + { + if ($this->connection && ! @ldap_close($this->connection)) + { + return false; + } + else + { + return true; + } + } - /** - * 2.1.3 : Anonymously binds to the connection. After this is done, - * queries and searches can be done - but read-only. - */ - function bind() - { - if (! $this->result=@ldap_bind($this->connection)) - { - $this->ldapErrorCode = ldap_errno($this->connection); - $this->ldapErrorText = ldap_error($this->connection); - $this->error=$this->ldapErrorCode." ".$this->ldapErrorText; - return false; - } - else - { - return true; - } - } + /** + * 2.1.3 : Anonymously binds to the connection. After this is done, + * queries and searches can be done - but read-only. + */ + function bind() + { + if (! $this->result=@ldap_bind($this->connection)) + { + $this->ldapErrorCode = ldap_errno($this->connection); + $this->ldapErrorText = ldap_error($this->connection); + $this->error=$this->ldapErrorCode." ".$this->ldapErrorText; + return false; + } + else + { + return true; + } + } - /** - * 2.1.4 : Binds as an authenticated user, which usually allows for write - * access. The FULL dn must be passed. For a directory manager, this is - * "cn=Directory Manager" under iPlanet. For a user, it will be something - * like "uid=jbloggs,ou=People,dc=foo,dc=com". - */ - function bindauth($bindDn,$pass) - { - if (! $this->result = @ldap_bind( $this->connection,$bindDn,$pass)) - { - $this->ldapErrorCode = ldap_errno($this->connection); - $this->ldapErrorText = ldap_error($this->connection); - $this->error=$this->ldapErrorCode." ".$this->ldapErrorText; - return false; - } - else - { - return true; - } - } + /** + * 2.1.4 : Binds as an authenticated user, which usually allows for write + * access. The FULL dn must be passed. For a directory manager, this is + * "cn=Directory Manager" under iPlanet. For a user, it will be something + * like "uid=jbloggs,ou=People,dc=foo,dc=com". + */ + function bindauth($bindDn,$pass) + { + if (! $this->result = @ldap_bind( $this->connection,$bindDn,$pass)) + { + $this->ldapErrorCode = ldap_errno($this->connection); + $this->ldapErrorText = ldap_error($this->connection); + $this->error=$this->ldapErrorCode." ".$this->ldapErrorText; + return false; + } + else + { + return true; + } + } - /** - * \brief Unbind du serveur ldap. - * \param ds - * \return bool - */ + /** + * \brief Unbind du serveur ldap. + * \param ds + * \return bool + */ function unbind() { if (!$this->result=@ldap_unbind($this->connection)) @@ -354,47 +355,47 @@ class Ldap } - /** - * \brief verification de la version du serveur ldap. - * \param ds - * \return version - */ - function getVersion() - { - $version = 0; - $version = @ldap_get_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $version); - return $version; - } + /** + * \brief verification de la version du serveur ldap. + * \param ds + * \return version + */ + function getVersion() + { + $version = 0; + $version = @ldap_get_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $version); + return $version; + } - /** - * \brief changement de la version du serveur ldap. - * \return version - */ - function setVersion() { + /** + * \brief changement de la version du serveur ldap. + * \return version + */ + function setVersion() { // LDAP_OPT_PROTOCOL_VERSION est une constante qui vaut 17 - $ldapsetversion = ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $this->ldapProtocolVersion); - return $ldapsetversion; - } + $ldapsetversion = ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $this->ldapProtocolVersion); + return $ldapsetversion; + } - /** - * \brief changement du referrals. - * \return referrals - */ - function setReferrals() { + /** + * \brief changement du referrals. + * \return referrals + */ + function setReferrals() { // LDAP_OPT_REFERRALS est une constante qui vaut ? - $ldapreferrals = ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0); - return $ldapreferrals; - } + $ldapreferrals = ldap_set_option($this->connection, LDAP_OPT_REFERRALS, 0); + return $ldapreferrals; + } /** - * \brief Mise à jour dans l'arbre LDAP - * \param dn DN - * \param info Tableau info - * \param user Objet user qui fait l'opération - * \return int <0 si ko, >0 si ok - * \remarks Ldap object connect and bind must have been done - */ + * \brief Mise à jour dans l'arbre LDAP + * \param dn DN + * \param info Tableau info + * \param user Objet user qui fait l'opération + * \return int <0 si ko, >0 si ok + * \remarks Ldap object connect and bind must have been done + */ function update($dn,$info,$user,$olddn='') { global $conf, $langs; @@ -432,73 +433,73 @@ class Ldap } - /** - * \brief Checks a username and password - does this by logging on to the - * server as a user - specified in the DN. There are several reasons why - * this login could fail - these are listed below. + /** + * \brief Checks a username and password - does this by logging on to the + * server as a user - specified in the DN. There are several reasons why + * this login could fail - these are listed below. * \return uname Username to check * \return pass Password to check * \return boolean true=check pass ok, falses=check pass failed - */ - function checkPass($uname,$pass) - { - /* Construct the full DN, eg:- - ** "uid=username, ou=People, dc=orgname,dc=com" - */ - if ($this->serverType == "activedirectory") { - // FQDN domain - $domain = eregi_replace('dc=','',$this->domain); - $domain = eregi_replace(',','.',$domain); - $checkDn = "$uname@$domain"; - } else { - $checkDn = $this->getUserIdentifier()."=".$uname.", ".$this->setDn(true); - } - // Try and connect... - $this->result = @ldap_bind( $this->connection,$checkDn,$pass); - if ( $this->result) { - // Connected OK - login credentials are fine! - $this->ldapUserDN = $checkDn; - return true; - } else { - /* Login failed. Return false, together with the error code and text from - ** the LDAP server. The common error codes and reasons are listed below : - ** (for iPlanet, other servers may differ) - ** 19 - Account locked out (too many invalid login attempts) - ** 32 - User does not exist - ** 49 - Wrong password - ** 53 - Account inactive (manually locked out by administrator) - */ - $this->ldapErrorCode = ldap_errno( $this->connection); - $this->ldapErrorText = ldap_error( $this->connection); - $this->ldapDebugDomain = $domain; - $this->ldapDebugDN = $checkDn; - return false; - } - } + */ + function checkPass($uname,$pass) + { + /* Construct the full DN, eg:- + ** "uid=username, ou=People, dc=orgname,dc=com" + */ + if ($this->serverType == "activedirectory") { + // FQDN domain + $domain = eregi_replace('dc=','',$this->domain); + $domain = eregi_replace(',','.',$domain); + $checkDn = "$uname@$domain"; + } else { + $checkDn = $this->getUserIdentifier()."=".$uname.", ".$this->setDn(true); + } + // Try and connect... + $this->result = @ldap_bind( $this->connection,$checkDn,$pass); + if ( $this->result) { + // Connected OK - login credentials are fine! + $this->ldapUserDN = $checkDn; + return true; + } else { + /* Login failed. Return false, together with the error code and text from + ** the LDAP server. The common error codes and reasons are listed below : + ** (for iPlanet, other servers may differ) + ** 19 - Account locked out (too many invalid login attempts) + ** 32 - User does not exist + ** 49 - Wrong password + ** 53 - Account inactive (manually locked out by administrator) + */ + $this->ldapErrorCode = ldap_errno( $this->connection); + $this->ldapErrorText = ldap_error( $this->connection); + $this->ldapDebugDomain = $domain; + $this->ldapDebugDN = $checkDn; + return false; + } + } - /* - * \brief Add a LDAP entry - * \param dn DN entry key - * \param info Attributes array - * \param user Objet utilisateru qui crée - * \return int <0 si KO, >0 si OK - */ + /** + * \brief Add a LDAP entry + * \param dn DN entry key + * \param info Attributes array + * \param user Objet utilisateru qui crée + * \return int <0 si KO, >0 si OK + */ function add($dn, $info, $user) { global $conf; dolibarr_syslog("Ldap::add dn=".$dn." info=".join(',',$info)); - // Encode en UTF8 - $dn=$this->ldap_utf8_encode($dn); + // Encode to LDAP page code + $dn=$this->convFromOutputCharset($dn,$this->ldapcharset); foreach($info as $key => $val) { - if (! is_array($val)) $info[$key]=$this->ldap_utf8_encode($val); + if (! is_array($val)) $info[$key]=$this->convFromOutputCharset($val,$this->ldapcharset); } $this->dump($dn,$info); - + //print_r($info); $result=@ldap_add($this->connection, $dn, $info); @@ -514,19 +515,19 @@ class Ldap } } - /* - * \brief Delete a LDAP entry - * \param dn DN entry key - * \return int <0 si KO, >0 si OK - */ + /** + * \brief Delete a LDAP entry + * \param dn DN entry key + * \return int <0 si KO, >0 si OK + */ function delete($dn) { global $conf; dolibarr_syslog("Ldap::delete Delete LDAP entry dn=".$dn); - // Encode en UTF8 - $dn=$this->ldap_utf8_encode($dn); + // Encode to LDAP page code + $dn=$this->convFromOutputCharset($dn,$this->ldapcharset); $result=@ldap_delete($this->connection, $dn); @@ -535,16 +536,16 @@ class Ldap } - /* - * \brief Build a LDAP message - * \param dn DN entry key - * \param info Attributes array - * \return string Content of file - */ + /** + * \brief Build a LDAP message + * \param dn DN entry key + * \param info Attributes array + * \return string Content of file + */ function dump_content($dn, $info) { $content=''; - + // Create file content if (ereg('^ldap',$this->server[0])) { @@ -557,7 +558,7 @@ class Ldap $content.="# ldapadd $target -c -v -D ".$this->searchUser." -W -f ldapinput.in\n"; $content.="# ldapmodify $target -c -v -D ".$this->searchUser." -W -f ldapinput.in\n"; $content.="# ldapdelete $target -c -v -D ".$this->searchUser." -W -f ldapinput.in\n"; - $content.="dn: ".$dn."\n"; + $content.="dn: ".$dn."\n"; foreach($info as $key => $value) { if (! is_array($value)) @@ -574,31 +575,31 @@ class Ldap } return $content; } - - /* - * \brief Dump a LDAP message to ldapinput.in file - * \param dn DN entry key - * \param info Attributes array - * \return int <0 if KO, >0 if OK - */ + + /** + * \brief Dump a LDAP message to ldapinput.in file + * \param dn DN entry key + * \param info Attributes array + * \return int <0 if KO, >0 if OK + */ function dump($dn, $info) { global $conf; // Create content $content=$this->dump_content($dn, $info); - + //Create file $result=create_exdir($conf->ldap->dir_temp); - + $file=$conf->ldap->dir_temp.'/ldapinput.in'; $fp=fopen($file,"w"); if ($fp) { fputs($fp, $content); fclose($fp); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + if (! empty($conf->global->MAIN_UMASK)) + @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); return 1; } else @@ -608,45 +609,45 @@ class Ldap } - // 2.4 Attribute methods ----------------------------------------------------- - /** - * 2.4.1 : Returns an array containing values for an attribute and for first record matching filterrecord - */ - function getAttribute($filterrecord,$attribute) - { - $attributes[0] = $attribute; + // 2.4 Attribute methods ----------------------------------------------------- + /** + * 2.4.1 : Returns an array containing values for an attribute and for first record matching filterrecord + */ + function getAttribute($filterrecord,$attribute) + { + $attributes[0] = $attribute; - // We need to search for this user in order to get their entry. - $this->result = @ldap_search($this->connection,$this->people,$filterrecord,$attributes); + // We need to search for this user in order to get their entry. + $this->result = @ldap_search($this->connection,$this->people,$filterrecord,$attributes); // Pourquoi cette ligne ? - //$info = ldap_get_entries($this->connection, $this->result); + //$info = ldap_get_entries($this->connection, $this->result); - // Only one entry should ever be returned (no user will have the same uid) - $entry = ldap_first_entry($this->connection, $this->result); + // Only one entry should ever be returned (no user will have the same uid) + $entry = ldap_first_entry($this->connection, $this->result); - if (!$entry) + if (!$entry) { - $this->ldapErrorCode = -1; - $this->ldapErrorText = "Couldn't find user"; - return false; // Couldn't find the user... - } + $this->ldapErrorCode = -1; + $this->ldapErrorText = "Couldn't find user"; + return false; // Couldn't find the user... + } - // Get values - if (! $values = @ldap_get_values( $this->connection, $entry, $attribute)) + // Get values + if (! $values = @ldap_get_values( $this->connection, $entry, $attribute)) { - $this->ldapErrorCode = ldap_errno( $this->connection); - $this->ldapErrorText = ldap_error( $this->connection); - return false; // No matching attributes - } + $this->ldapErrorCode = ldap_errno( $this->connection); + $this->ldapErrorText = ldap_error( $this->connection); + return false; // No matching attributes + } - // Return an array containing the attributes. - return $values; - } + // Return an array containing the attributes. + return $values; + } - /** - * \brief Returns an array containing a details of elements + /** + * \brief Returns an array containing a details of elements * \param $search Valeur champ clé recherché, sinon '*' pour tous. * \param $userDn DN (Ex: ou=adherents,ou=people,dc=parinux,dc=org) * \param $useridentifier Nom du champ clé (Ex: uid) @@ -654,56 +655,56 @@ class Ldap * \param $activefilter 1=utilise le champ this->filter comme filtre * \return array Array of [id_record][ldap_field]=value * \remarks ldapsearch -LLLx -hlocalhost -Dcn=admin,dc=parinux,dc=org -w password -b "ou=adherents,ou=people,dc=parinux,dc=org" userPassword - */ - function getRecords($search, $userDn, $useridentifier, $attributeArray, $activefilter=0) - { - $fulllist=array(); - - dolibarr_syslog("Ldap::getRecords search=".$search." userDn=".$userDn." useridentifier=".$useridentifier." attributeArray=array(".join(',',$attributeArray).")"); + */ + function getRecords($search, $userDn, $useridentifier, $attributeArray, $activefilter=0) + { + $fulllist=array(); - // if the directory is AD, then bind first with the search user first - if ($this->serverType == "activedirectory") - { - $this->bindauth($this->searchUser, $this->searchPassword); - dolibarr_syslog("Ldap::bindauth serverType=activedirectory searchUser=".$this->searchUser); - } + dolibarr_syslog("Ldap::getRecords search=".$search." userDn=".$userDn." useridentifier=".$useridentifier." attributeArray=array(".join(',',$attributeArray).")"); - // Define filter - if ($activefilter == 1) - { - if ($this->filter) - { - $filter = '('.$this->filter.')'; - } - else - { - $filter='('.$useridentifier.'=*)'; - } - } - else - { - $filter = '('.$useridentifier.'='.$search.')'; - } + // if the directory is AD, then bind first with the search user first + if ($this->serverType == "activedirectory") + { + $this->bindauth($this->searchUser, $this->searchPassword); + dolibarr_syslog("Ldap::bindauth serverType=activedirectory searchUser=".$this->searchUser); + } - if (is_array($attributeArray)) - { - // Return list with required fields - dolibarr_syslog("Ldap::getRecords connection=".$this->connection." userDn=".$userDn." filter=".$filter. " attributeArray=(".join(',',$attributeArray).")"); - $this->result = @ldap_search($this->connection, $userDn, $filter, $attributeArray); - } - else - { - // Return list with fields selected by default - dolibarr_syslog("Ldap::getRecords connection=".$this->connection." userDn=".$userDn." filter=".$filter); - $this->result = @ldap_search($this->connection, $userDn, $filter); - } - if (!$this->result) - { - $this->error = 'LDAP search failed: '.ldap_errno($this->connection)." ".ldap_error($this->connection); - return -1; - } + // Define filter + if ($activefilter == 1) + { + if ($this->filter) + { + $filter = '('.$this->filter.')'; + } + else + { + $filter='('.$useridentifier.'=*)'; + } + } + else + { + $filter = '('.$useridentifier.'='.$search.')'; + } - $info = @ldap_get_entries($this->connection, $this->result); + if (is_array($attributeArray)) + { + // Return list with required fields + dolibarr_syslog("Ldap::getRecords connection=".$this->connection." userDn=".$userDn." filter=".$filter. " attributeArray=(".join(',',$attributeArray).")"); + $this->result = @ldap_search($this->connection, $userDn, $filter, $attributeArray); + } + else + { + // Return list with fields selected by default + dolibarr_syslog("Ldap::getRecords connection=".$this->connection." userDn=".$userDn." filter=".$filter); + $this->result = @ldap_search($this->connection, $userDn, $filter); + } + if (!$this->result) + { + $this->error = 'LDAP search failed: '.ldap_errno($this->connection)." ".ldap_error($this->connection); + return -1; + } + + $info = @ldap_get_entries($this->connection, $this->result); // Warning: Dans info, les noms d'attributs sont en minuscule meme si passé // a ldap_search en majuscule !!! @@ -711,18 +712,18 @@ class Ldap for ($i = 0; $i < $info["count"]; $i++) { - $recordid=$this->ldap_utf8_decode($info[$i][$useridentifier][0]); + $recordid=$this->convToOutputCharset($info[$i][$useridentifier][0],$this->ldapcharset); if ($recordid) { //print "Found record with key $useridentifier=".$recordid."
\n"; $fulllist[$recordid][$useridentifier]=$recordid; - + // Add to the array for each attribute in my list for ($j = 0; $j < count($attributeArray); $j++) { $keyattributelower=strtolower($attributeArray[$j]); //print " Param ".$attributeArray[$j]."=".$info[$i][$keyattributelower][0]."
\n"; - + //permet de récupérer le SID avec Active Directory if ($this->serverType == "activedirectory" && $keyattributelower == "objectsid") { @@ -731,119 +732,119 @@ class Ldap } else { - $fulllist[$recordid][$attributeArray[$j]] = $this->ldap_utf8_decode($info[$i][$keyattributelower][0]); + $fulllist[$recordid][$attributeArray[$j]] = $this->convToOutputCharset($info[$i][$keyattributelower][0],$this->ldapcharset); } } } } - asort($fulllist); - return $fulllist; - } - - /** - * Converts a little-endian hex-number to one, that 'hexdec' can convert - * Indispensable pour Active Directory - */ - function littleEndian($hex) { - for ($x=strlen($hex)-2; $x >= 0; $x=$x-2) { - $result .= substr($hex,$x,2); - } - return $result; - } - - - /** - * Récupère le SID de l'utilisateur - * ldapuser. le login de l'utilisateur - * Indispensable pour Active Directory - */ - function getObjectSid($ldapUser) - { - $criteria = '('.$this->getUserIdentifier().'='.$ldapUser.')'; - $justthese = array("objectsid"); - - // if the directory is AD, then bind first with the search user first - if ($this->serverType == "activedirectory") - { - $this->bindauth($this->searchUser, $this->searchPassword); - } - - $i = 0; - $searchDN = $this->people; - - while ($i <= 2) - { - $ldapSearchResult = @ldap_search($this->connection, $searchDN, $criteria, $justthese); - - if (!$ldapSearchResult) - { - $this->error = ldap_errno($this->connection)." ".ldap_error($this->connection); - return -1; - } - - $entry = ldap_first_entry($this->connection, $ldapSearchResult); - - if (!$entry) - { - // Si pas de résultat on cherche dans le domaine - $searchDN = $this->domain; - $i++; - } - else - { - $i++; - $i++; - } - } - - if ($entry) - { - $ldapBinary = ldap_get_values_len ($this->connection, $entry, "objectsid"); - $SIDText = $this->binSIDtoText($ldapBinary[0]); - return $SIDText; - } - else - { - $this->error = ldap_errno($this->connection)." ".ldap_error($this->connection); - return '?'; - } - } - - /** - * Returns the textual SID - * Indispensable pour Active Directory - */ - function binSIDtoText($binsid) { - $hex_sid=bin2hex($binsid); - $rev = hexdec(substr($hex_sid,0,2)); // Get revision-part of SID - $subcount = hexdec(substr($hex_sid,2,2)); // Get count of sub-auth entries - $auth = hexdec(substr($hex_sid,4,12)); // SECURITY_NT_AUTHORITY - $result = "$rev-$auth"; - for ($x=0;$x < $subcount; $x++) { - $subauth[$x] = hexdec($this->littleEndian(substr($hex_sid,16+($x*8),8))); // get all SECURITY_NT_AUTHORITY - $result .= "-".$subauth[$x]; - } - return $result; - } - + asort($fulllist); + return $fulllist; + } /** - * \brief Fonction de recherche avec filtre - * \remarks this->connection doit etre défini donc la methode bind ou bindauth doit avoir deja été appelée - * \param checkDn DN de recherche (Ex: ou=users,cn=my-domain,cn=com) - * \param filter Filtre de recherche (ex: (sn=nom_personne) ) - * \return array Tableau des reponses (clé en minuscule-valeur) - * \remarks Ne pas utiliser pour recherche d'une liste donnée de propriétés - * car conflit majuscule-minuscule. A n'utiliser que pour les pages - * 'Fiche LDAP' qui affiche champ lisibles par defaut. - */ + * Converts a little-endian hex-number to one, that 'hexdec' can convert + * Indispensable pour Active Directory + */ + function littleEndian($hex) { + for ($x=strlen($hex)-2; $x >= 0; $x=$x-2) { + $result .= substr($hex,$x,2); + } + return $result; + } + + + /** + * Récupère le SID de l'utilisateur + * ldapuser. le login de l'utilisateur + * Indispensable pour Active Directory + */ + function getObjectSid($ldapUser) + { + $criteria = '('.$this->getUserIdentifier().'='.$ldapUser.')'; + $justthese = array("objectsid"); + + // if the directory is AD, then bind first with the search user first + if ($this->serverType == "activedirectory") + { + $this->bindauth($this->searchUser, $this->searchPassword); + } + + $i = 0; + $searchDN = $this->people; + + while ($i <= 2) + { + $ldapSearchResult = @ldap_search($this->connection, $searchDN, $criteria, $justthese); + + if (!$ldapSearchResult) + { + $this->error = ldap_errno($this->connection)." ".ldap_error($this->connection); + return -1; + } + + $entry = ldap_first_entry($this->connection, $ldapSearchResult); + + if (!$entry) + { + // Si pas de résultat on cherche dans le domaine + $searchDN = $this->domain; + $i++; + } + else + { + $i++; + $i++; + } + } + + if ($entry) + { + $ldapBinary = ldap_get_values_len ($this->connection, $entry, "objectsid"); + $SIDText = $this->binSIDtoText($ldapBinary[0]); + return $SIDText; + } + else + { + $this->error = ldap_errno($this->connection)." ".ldap_error($this->connection); + return '?'; + } + } + + /** + * Returns the textual SID + * Indispensable pour Active Directory + */ + function binSIDtoText($binsid) { + $hex_sid=bin2hex($binsid); + $rev = hexdec(substr($hex_sid,0,2)); // Get revision-part of SID + $subcount = hexdec(substr($hex_sid,2,2)); // Get count of sub-auth entries + $auth = hexdec(substr($hex_sid,4,12)); // SECURITY_NT_AUTHORITY + $result = "$rev-$auth"; + for ($x=0;$x < $subcount; $x++) { + $subauth[$x] = hexdec($this->littleEndian(substr($hex_sid,16+($x*8),8))); // get all SECURITY_NT_AUTHORITY + $result .= "-".$subauth[$x]; + } + return $result; + } + + + /** + * \brief Fonction de recherche avec filtre + * \remarks this->connection doit etre défini donc la methode bind ou bindauth doit avoir deja été appelée + * \param checkDn DN de recherche (Ex: ou=users,cn=my-domain,cn=com) + * \param filter Filtre de recherche (ex: (sn=nom_personne) ) + * \return array Tableau des reponses (clé en minuscule-valeur) + * \remarks Ne pas utiliser pour recherche d'une liste donnée de propriétés + * car conflit majuscule-minuscule. A n'utiliser que pour les pages + * 'Fiche LDAP' qui affiche champ lisibles par defaut. + */ function search($checkDn, $filter) { dolibarr_syslog("Ldap::search checkDn=".$checkDn." filter=".$filter); - $checkDn=$this->ldap_utf8_encode($checkDn); - $filter=$this->ldap_utf8_encode($filter); + $checkDn=$this->convFromOutputCharset($checkDn,$this->ldapcharset); + $filter=$this->convFromOutputCharset($filter,$this->ldapcharset); // if the directory is AD, then bind first with the search user first if ($this->serverType == "activedirectory") { @@ -866,12 +867,12 @@ class Ldap } - /** - * \brief Récupère les attributs de l'utilisateur - * \param $user Utilisateur ldap à lire + /** + * \brief Récupère les attributs de l'utilisateur + * \param $user Utilisateur ldap à lire * \return int >0 if ok, <0 if ko - */ - function fetch($user) + */ + function fetch($user) { // Perform the search and get the entry handles @@ -882,16 +883,16 @@ class Ldap $userIdentifier = $this->getUserIdentifier(); $filter = '('.$this->filter.'('.$userIdentifier.'='.$user.'))'; - + $i = 0; $searchDN = $this->people; - + $result = ''; - + while ($i <= 2) { $this->result = @ldap_search($this->connection, $searchDN, $filter); - + if ($this->result) { $result = @ldap_get_entries($this->connection, $this->result); @@ -902,7 +903,7 @@ class Ldap $this->error = ldap_errno($this->connection)." ".ldap_error($this->connection); return -1; } - + if (!$result) { // Si pas de résultat on cherche dans le domaine @@ -923,26 +924,26 @@ class Ldap } else { - $this->name = $this->ldap_utf8_decode($result[0][$this->attr_name][0]); - $this->firstname = $this->ldap_utf8_decode($result[0][$this->attr_firstname][0]); - $this->login = $this->ldap_utf8_decode($result[0][$userIdentifier][0]); - $this->phone = $this->ldap_utf8_decode($result[0][$this->attr_phone][0]); - $this->fax = $this->ldap_utf8_decode($result[0][$this->attr_fax][0]); - $this->mail = $this->ldap_utf8_decode($result[0][$this->attr_mail][0]); - $this->mobile = $this->ldap_utf8_decode($result[0][$this->attr_mobile][0]); + $this->name = $this->convToOutputCharset($result[0][$this->attr_name][0],$this->ldapcharset); + $this->firstname = $this->convToOutputCharset($result[0][$this->attr_firstname][0],$this->ldapcharset); + $this->login = $this->convToOutputCharset($result[0][$userIdentifier][0],$this->ldapcharset); + $this->phone = $this->convToOutputCharset($result[0][$this->attr_phone][0],$this->ldapcharset); + $this->fax = $this->convToOutputCharset($result[0][$this->attr_fax][0],$this->ldapcharset); + $this->mail = $this->convToOutputCharset($result[0][$this->attr_mail][0],$this->ldapcharset); + $this->mobile = $this->convToOutputCharset($result[0][$this->attr_mobile][0],$this->ldapcharset); - $this->uacf = $this->parseUACF($this->ldap_utf8_decode($result[0]["useraccountcontrol"][0])); + $this->uacf = $this->parseUACF($this->convToOutputCharset($result[0]["useraccountcontrol"][0],$this->ldapcharset)); if (isset($result[0]["pwdlastset"][0])) // If expiration on password exists { - $this->pwdlastset = ($result[0]["pwdlastset"][0] != 0)?$this->convert_time($this->ldap_utf8_decode($result[0]["pwdlastset"][0])):0; + $this->pwdlastset = ($result[0]["pwdlastset"][0] != 0)?$this->convert_time($this->convToOutputCharset($result[0]["pwdlastset"][0],$this->ldapcharset)):0; } else { $this->pwdlastset = -1; } if (!$this->name && !$this->login) $this->pwdlastset = -1; - $this->badpwdtime = $this->convert_time($this->ldap_utf8_decode($result[0]["badpasswordtime"][0])); - + $this->badpwdtime = $this->convert_time($this->convToOutputCharset($result[0]["badpasswordtime"][0],$this->ldapcharset)); + // FQDN domain $domain = eregi_replace('dc=','',$this->domain); $domain = eregi_replace(',','.',$domain); @@ -952,53 +953,53 @@ class Ldap return 1; } } - - // 2.6 helper methods - /** - * Sets and returns the appropriate dn, based on whether there - * are values in $this->people and $this->groups. - * - * @param boolean specifies whether to build a groups dn or a people dn - * @return string if true ou=$this->people,$this->dn, else ou=$this->groups,$this->dn - */ - function setDn($peopleOrGroups) { + // 2.6 helper methods - if ($peopleOrGroups) { - if ( isset($this->people) && (strlen($this->people) > 0) ) { - $checkDn = "ou=" .$this->people. ", " .$this->dn; - } - } else { - if ( isset($this->groups) && (strlen($this->groups) > 0) ) { - $checkDn = "ou=" .$this->groups. ", " .$this->dn; - } - } + /** + * Sets and returns the appropriate dn, based on whether there + * are values in $this->people and $this->groups. + * + * @param boolean specifies whether to build a groups dn or a people dn + * @return string if true ou=$this->people,$this->dn, else ou=$this->groups,$this->dn + */ + function setDn($peopleOrGroups) { - if ( !isset($checkDn) ) { - $checkDn = $this->dn; - } - return $checkDn; - } + if ($peopleOrGroups) { + if ( isset($this->people) && (strlen($this->people) > 0) ) { + $checkDn = "ou=" .$this->people. ", " .$this->dn; + } + } else { + if ( isset($this->groups) && (strlen($this->groups) > 0) ) { + $checkDn = "ou=" .$this->groups. ", " .$this->dn; + } + } - /** - * Returns the correct user identifier to use, based on the ldap server type - */ - function getUserIdentifier() { - if ($this->serverType == "activedirectory") { - return $this->attr_sambalogin; - } else { - return $this->attr_login; - } - } + if ( !isset($checkDn) ) { + $checkDn = $this->dn; + } + return $checkDn; + } - /** + /** + * Returns the correct user identifier to use, based on the ldap server type + */ + function getUserIdentifier() { + if ($this->serverType == "activedirectory") { + return $this->attr_sambalogin; + } else { + return $this->attr_login; + } + } + + /** * \brief UserAccountControl Flgs to more human understandable form... * */ - function parseUACF($uacf) { - //All flags array - $flags = array( "TRUSTED_TO_AUTH_FOR_DELEGATION" => 16777216, + function parseUACF($uacf) { + //All flags array + $flags = array( "TRUSTED_TO_AUTH_FOR_DELEGATION" => 16777216, "PASSWORD_EXPIRED" => 8388608, "DONT_REQ_PREAUTH" => 4194304, "USE_DES_KEY_ONLY" => 2097152, @@ -1020,107 +1021,111 @@ class Ldap "ACCOUNTDISABLE" => 2, "SCRIPT" => 1); - //Parse flags to text - $retval = array(); - while (list($flag, $val) = each($flags)) { - if ($uacf >= $val) { - $uacf -= $val; - $retval[$val] = $flag; - } - } + //Parse flags to text + $retval = array(); + while (list($flag, $val) = each($flags)) { + if ($uacf >= $val) { + $uacf -= $val; + $retval[$val] = $flag; + } + } - //Return human friendly flags - return($retval); - } + //Return human friendly flags + return($retval); + } - /** + /** * \brief SamAccountType value to text * */ - function parseSAT($samtype) { - $stypes = array( 805306368 => "NORMAL_ACCOUNT", - 805306369 => "WORKSTATION_TRUST", - 805306370 => "INTERDOMAIN_TRUST", - 268435456 => "SECURITY_GLOBAL_GROUP", - 268435457 => "DISTRIBUTION_GROUP", - 536870912 => "SECURITY_LOCAL_GROUP", - 536870913 => "DISTRIBUTION_LOCAL_GROUP"); + function parseSAT($samtype) { + $stypes = array( 805306368 => "NORMAL_ACCOUNT", + 805306369 => "WORKSTATION_TRUST", + 805306370 => "INTERDOMAIN_TRUST", + 268435456 => "SECURITY_GLOBAL_GROUP", + 268435457 => "DISTRIBUTION_GROUP", + 536870912 => "SECURITY_LOCAL_GROUP", + 536870913 => "DISTRIBUTION_LOCAL_GROUP"); - $retval = ""; - while (list($sat, $val) = each($stypes)) { - if ($samtype == $sat) { - $retval = $val; - break; - } - } - if (empty($retval)) $retval = "UNKNOWN_TYPE_" . $samtype; + $retval = ""; + while (list($sat, $val) = each($stypes)) { + if ($samtype == $sat) { + $retval = $val; + break; + } + } + if (empty($retval)) $retval = "UNKNOWN_TYPE_" . $samtype; - return($retval); - } + return($retval); + } - /** + /** * \Parse GroupType value to text * */ - function parseGT($grouptype) { - $gtypes = array( -2147483643 => "SECURITY_BUILTIN_LOCAL_GROUP", - -2147483644 => "SECURITY_DOMAIN_LOCAL_GROUP", - -2147483646 => "SECURITY_GLOBAL_GROUP", - 2 => "DISTRIBUTION_GLOBAL_GROUP", - 4 => "DISTRIBUTION_DOMAIN_LOCAL_GROUP", - 8 => "DISTRIBUTION_UNIVERSAL_GROUP"); + function parseGT($grouptype) { + $gtypes = array( -2147483643 => "SECURITY_BUILTIN_LOCAL_GROUP", + -2147483644 => "SECURITY_DOMAIN_LOCAL_GROUP", + -2147483646 => "SECURITY_GLOBAL_GROUP", + 2 => "DISTRIBUTION_GLOBAL_GROUP", + 4 => "DISTRIBUTION_DOMAIN_LOCAL_GROUP", + 8 => "DISTRIBUTION_UNIVERSAL_GROUP"); - $retval = ""; - while (list($gt, $val) = each($gtypes)) { - if ($grouptype == $gt) { - $retval = $val; - break; - } - } - if (empty($retval)) $retval = "UNKNOWN_TYPE_" . $grouptype; + $retval = ""; + while (list($gt, $val) = each($gtypes)) { + if ($grouptype == $gt) { + $retval = $val; + break; + } + } + if (empty($retval)) $retval = "UNKNOWN_TYPE_" . $grouptype; - return($retval); - } - - - /* - * \brief Encode in UTF8 or not - * \param string String to decode - * \return string String decoded - */ - function ldap_utf8_encode($string) - { - if ($this->serverType != "activedirectory") return utf8_encode($string); - else return($string); + return($retval); } - + /* - * \brief Decode in UTF8 or not - * \param string String to decode - * \return string String decoded - */ - function ldap_utf8_decode($string) - { - //if ($this->serverType != "activedirectory") return utf8_decode($string); - //else return($string); - return utf8_decode($string); //utile aussi avec Active Directory - Regis - } - - /* - * \brief Convertit le temps ActiveDirectory en Unix timestamp - * \param string AD time to convert - * \return string Unix timestamp - */ + * \brief Convertit le temps ActiveDirectory en Unix timestamp + * \param string AD time to convert + * \return string Unix timestamp + */ function convert_time($value) - { - $dateLargeInt=$value; // nano secondes depuis 1601 !!!! - $secsAfterADEpoch = $dateLargeInt / (10000000); // secondes depuis le 1 jan 1601 - $ADToUnixConvertor=((1970-1601) * 365.242190) * 86400; // UNIX start date - AD start date * jours * secondes - $unixTimeStamp=intval($secsAfterADEpoch-$ADToUnixConvertor); // Unix time stamp - return $unixTimeStamp; - } + { + $dateLargeInt=$value; // nano secondes depuis 1601 !!!! + $secsAfterADEpoch = $dateLargeInt / (10000000); // secondes depuis le 1 jan 1601 + $ADToUnixConvertor=((1970-1601) * 365.242190) * 86400; // UNIX start date - AD start date * jours * secondes + $unixTimeStamp=intval($secsAfterADEpoch-$ADToUnixConvertor); // Unix time stamp + return $unixTimeStamp; + } + + /** + * \brief Convert a string into output/memory charset + * \param str String to convert + * \param pagecodefrom Page code of src string + * \return string Converted string + */ + function convToOutputCharset($str,$pagecodefrom='UTF-8') + { + global $conf; + if ($pagecodefrom == 'ISO-8859-1' && $conf->character_set_client == 'UTF-8') $str=utf8_encode($str); + if ($pagecodefrom == 'UTF-8' && $conf->character_set_client == 'ISO-8859-1') $str=utf8_decode($str); + return $str; + } + + /** + * \brief Convert a string from output/memory charset + * \param str String to convert + * \param pagecodeto Page code for result string + * \return string Converted string + */ + function convFromOutputCharset($str,$pagecodeto='UTF-8') + { + global $conf; + if ($pagecodeto == 'ISO-8859-1' && $conf->character_set_client == 'UTF-8') $str=utf8_decode($str); + if ($pagecodeto == 'UTF-8' && $conf->character_set_client == 'ISO-8859-1') $str=utf8_encode($str); + return $str; + } } diff --git a/htdocs/lib/ldap.lib.php b/htdocs/lib/ldap.lib.php index 17bd45412b4..5ec4f74e791 100644 --- a/htdocs/lib/ldap.lib.php +++ b/htdocs/lib/ldap.lib.php @@ -79,6 +79,46 @@ function ldap_prepare_head() } +/** + * \brief Show button test LDAP synchro + */ +function show_ldap_test_button($butlabel,$testlabel,$key,$dn,$objectclass) +{ + global $langs, $conf, $user; + //print 'key='.$key.' dn='.$dn.' objectclass='.$objectclass; + + print '
'; + if (! function_exists("ldap_connect")) + { + print ''.$butlabel.''; + } + else if (empty($conf->global->LDAP_SERVER_HOST)) + { + print ''.$butlabel.''; + } + else if (empty($key) || empty($dn) || empty($objectclass)) + { + $langs->load("errors"); + print ''.$butlabel.''; + } + else + { + print ''.$butlabel.''; + } + print '

'; +} + + +/** + * Show an LDAP array in an HTML to records. + * + * @param unknown_type $result Array to show. This array is already encoded into charset_output + * @param unknown_type $level + * @param unknown_type $count + * @param unknown_type $var + * @param unknown_type $hide + * @return unknown + */ function show_ldap_content($result,$level,$count,$var,$hide=0) { global $bc, $conf; @@ -113,8 +153,8 @@ function show_ldap_content($result,$level,$count,$var,$hide=0) } else { - if ($hide) print eregi_replace('.','*',utf8_decode("$val")); - else print utf8_decode($val); + if ($hide) print eregi_replace('.','*',$val); + else print $val; print ''; } } diff --git a/htdocs/translate.class.php b/htdocs/translate.class.php index e3c97afd714..9e73e4475ef 100644 --- a/htdocs/translate.class.php +++ b/htdocs/translate.class.php @@ -42,8 +42,8 @@ class Translate { var $cache_labels=array(); // Cache for labels - var $charset_inputfile='ISO-8859-1'; // Codage used by default to encode lang files (used if CHARSET not found in file) - var $charset_output='UTF-8'; // Codage used by default for "trans" method output if $conf->character_set_client not defined (character_set_client in conf.php) + var $charset_inputfile='ISO-8859-1'; // Codage used by default to encode/decode lang files (used if CHARSET not found in file) + var $charset_output='UTF-8'; // Codage used by default for "trans" method output if $conf->character_set_client not defined (should never happen) /**