';
if ($conf->global->LDAP_ADMIN_PASS)
{
- print '';// je le met en visible pour test
+ print '';// je le met en visible pour test
}
else
{
@@ -274,7 +295,7 @@ if ($conf->global->LDAP_FILTER_CONNECTION)
}
else
{
- print '';
+ print '';
}
print '
'.$langs->trans("LDAPFilterConnectionExample").'
';
@@ -381,11 +402,11 @@ if (function_exists("ldap_connect"))
if ($conf->global->LDAP_SERVER_HOST && $conf->global->LDAP_ADMIN_DN && $conf->global->LDAP_ADMIN_PASS && $_GET["action"] == 'test')
{
- $ldap = New Ldap();
+ $ldap = New AuthLdap();
// Test ldap_connect
// ce test n'est pas fiable car une ressource est constamment retournée
// il faut se fier au test ldap_bind
- $ds = $ldap->dolibarr_ldap_connect();
+ $ds = $ldap->connect();
if ($ds)
{
print img_picto('','info');
@@ -396,14 +417,14 @@ if (function_exists("ldap_connect"))
print img_picto('','alerte');
print $langs->trans("LDAPTestKO").' ';
print " ";
- print $ldap->err;
+ print $ldap->ldapErrorCode." - ".$ldap->ldapErrorText;
print " ";
}
if ($ds)
{
// Test ldap_getversion
- if (($ldap->dolibarr_ldap_getversion($ds) == 3))
+ if (($ldap->getVersion() == 3))
{
print img_picto('','info');
print $langs->trans("LDAPSetupForVersion3").' ';
@@ -415,7 +436,7 @@ if (function_exists("ldap_connect"))
}
// Test ldap_bind
- $bind = $ldap->dolibarr_ldap_bind($ds);
+ $bind = $ldap->bind();
if ($bind)
{
@@ -426,14 +447,14 @@ if (function_exists("ldap_connect"))
{
print img_picto('','alerte');
print "Connexion au dn $dn raté : ";
- print $ldap->err;
+ print $ldap->ldapErrorCode." - ".$ldap->ldapErrorText;
print " ";
}
// Test ldap_unbind
- $unbind = $ldap->dolibarr_ldap_unbind($ds);
+ $unbind = $ldap->unbind();
- if ($bind && $unbind)
+ if ($unbind)
{
print img_picto('','info');
print "Déconnection du dn $dn réussi ";
@@ -443,6 +464,7 @@ if (function_exists("ldap_connect"))
print img_picto('','alerte');
print "Déconnection du dn $dn raté";
print " ";
+ print $ldap->ldapErrorCode." - ".$ldap->ldapErrorText;
}
}
}
diff --git a/htdocs/conf/conf.class.php b/htdocs/conf/conf.class.php
index 57dc35e750b..f4324b7ee45 100644
--- a/htdocs/conf/conf.class.php
+++ b/htdocs/conf/conf.class.php
@@ -275,6 +275,8 @@ class Conf
// Module export
$this->export->enabled=defined("MAIN_MODULE_EXPORT")?MAIN_MODULE_EXPORT:0;
$this->export->dir_ouput=DOL_DATA_ROOT."/export";
+ // Module ldap
+ $this->ldap->enabled=defined("MAIN_MODULE_LDAP")?MAIN_MODULE_LDAP:0;
/*
diff --git a/htdocs/contact.class.php b/htdocs/contact.class.php
index e375c496257..8c7fd07f1da 100644
--- a/htdocs/contact.class.php
+++ b/htdocs/contact.class.php
@@ -186,17 +186,14 @@ class Contact
dolibarr_syslog("Contact::update_ldap",LOG_DEBUG);
$this->fetch($this->id);
+ $ldap = New AuthLdap();
- $ds = dolibarr_ldap_connect();
-
- if ($ds)
- {
- $ldapbind = dolibarr_ldap_bind($ds);
-
- if ($ldapbind)
- {
- if (LDAP_SERVER_TYPE == 'activedirectory') //enlever utf8 pour etre compatible Windows
- {
+ if ($ldap->connect())
+ {
+ if (bind())
+ {
+ if (LDAP_SERVER_TYPE == 'activedirectory') //enlever utf8 pour etre compatible Windows
+ {
$info["objectclass"][0] = "top";
$info["objectclass"][1] = "person";
$info["objectclass"][2] = "organizationalPerson";
@@ -207,33 +204,41 @@ class Contact
$info["sn"] = $this->name;
$info["givenName"] = $this->firstname;
- if ($this->poste)
- $info["title"] = $this->poste;
+ if ($this->poste) $info["title"] = $this->poste;
if ($this->socid > 0)
- {
- $soc = new Societe($this->db);
- $soc->fetch($this->socid);
- $info["o"] = $soc->nom;
- $info["company"] = $soc->nom;
-
- if ($soc->client == 1)
- $info["businessCategory"] = "Clients";
- elseif ($soc->client == 2)
- $info["businessCategory"] = "Prospects";
-
- if ($soc->fournisseur == 1)
- $info["businessCategory"] = "Fournisseurs";
-
- if ($soc->ville)
- {
- if ($soc->adresse)
- $info["streetAddress"] = $soc->adresse;
-
- if ($soc->cp)
- $info["postalCode"] = $soc->cp;
-
- $info["l"] = $soc->ville;
+ {
+ $soc = new Societe($this->db);
+ $soc->fetch($this->socid);
+ $info["o"] = $soc->nom;
+ $info["company"] = $soc->nom;
+
+ if ($soc->client == 1)
+ {
+ $info["businessCategory"] = "Clients";
+ }
+ elseif ($soc->client == 2)
+ {
+ $info["businessCategory"] = "Prospects";
+ }
+
+ if ($soc->fournisseur == 1)
+ {
+ $info["businessCategory"] = "Fournisseurs";
+ }
+
+ if ($soc->ville)
+ {
+ if ($soc->adresse)
+ {
+ $info["streetAddress"] = $soc->adresse;
+ }
+ if ($soc->cp)
+ {
+ $info["postalCode"] = $soc->cp;
+ }
+
+ $info["l"] = $soc->ville;
}
}
@@ -370,7 +375,7 @@ class Contact
dolibarr_syslog("Contact::update_ldap bind failed",LOG_DEBUG);
}
- dolibarr_ldap_unbind($ds);
+ $ldap->unbind();
}
else
@@ -636,46 +641,42 @@ class Contact
{
if (defined('LDAP_CONTACT_ACTIVE') && LDAP_CONTACT_ACTIVE == 1)
{
+ $ldap = New AuthLdap();
- $ds = dolibarr_ldap_connect();
-
- if ($ds)
- {
- $ldapbind = dolibarr_ldap_bind($ds);
-
- if ($ldapbind)
- {
- // delete from ldap directory
- if (LDAP_SERVER_TYPE == 'activedirectory')
- {
- $userdn = $this->old_firstname." ".$this->old_name; //enlever utf8 pour etre compatible Windows
- }
- else
- {
- $userdn = utf8_encode($this->old_firstname." ".$this->old_name);
- }
- $dn = "cn=".$userdn.",".LDAP_CONTACT_DN;
-
- $r = @ldap_delete($ds, $dn);
-
- }
- else
- {
- echo "LDAP bind failed...";
- }
- ldap_close($ds);
-
- }
+ if ($ldap->connect())
+ {
+ if ($ldap->bind())
+ {
+ // delete from ldap directory
+ if (LDAP_SERVER_TYPE == 'activedirectory')
+ {
+ $userdn = $this->old_firstname." ".$this->old_name; //enlever utf8 pour etre compatible Windows
+ }
+ else
+ {
+ $userdn = utf8_encode($this->old_firstname." ".$this->old_name);
+ }
+
+ $dn = "cn=".$userdn.",".LDAP_CONTACT_DN;
+ $r = @ldap_delete($ds, $dn);
+ }
+ else
+ {
+ echo "LDAP bind failed...";
+ }
+
+ $ldap->close();
+ }
else
- {
- echo "Unable to connect to LDAP server";
- }
-
+ {
+ echo "Unable to connect to LDAP server";
+ }
return $result;
}
+ }
}
- }
+
/*
* \brief Charge les informations sur le contact, depuis la base
diff --git a/htdocs/langs/en_US/users.lang b/htdocs/langs/en_US/users.lang
index 026daa3a34f..26758763b6f 100755
--- a/htdocs/langs/en_US/users.lang
+++ b/htdocs/langs/en_US/users.lang
@@ -72,4 +72,5 @@ ErrorFailedToSaveFile=Error - Failed to save file
GuiLanguage=Interface language
InternalUser=Internal user
MyInformations=My informations
-ExportDataset_user_1=Dolibarr's users and properties
\ No newline at end of file
+ExportDataset_user_1=Dolibarr's users and properties
+DomainUser=Domain user
\ No newline at end of file
diff --git a/htdocs/langs/fr_FR/users.lang b/htdocs/langs/fr_FR/users.lang
index 397d44667ed..3e4599165c7 100755
--- a/htdocs/langs/fr_FR/users.lang
+++ b/htdocs/langs/fr_FR/users.lang
@@ -73,3 +73,4 @@ GuiLanguage=Langage de l'interface
InternalUser=Utilisateur interne
MyInformations=Mes informations
ExportDataset_user_1=Utilisateurs Dolibarr et attributs
+DomainUser=Utilisateur du domaine
\ No newline at end of file
diff --git a/htdocs/lib/authldap.lib.php b/htdocs/lib/authldap.lib.php
new file mode 100644
index 00000000000..c969bcfab99
--- /dev/null
+++ b/htdocs/lib/authldap.lib.php
@@ -0,0 +1,608 @@
+
+ * Copyright (C) 2004 Benoit Mortier
+ * Copyright (C) 2005-2006 Regis Houssin
+ * Copyright (C) 2006 Laurent Destailleur
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * or see http://www.gnu.org/
+ *
+ * $Id$
+ * $Source$
+ */
+
+/**
+ \file htdocs/lib/authldap.lib.php
+ \brief Librairie contenant les fonctions pour accèder au serveur ldap.
+ \author Rodolphe Quiedeville.
+ \author Benoit Mortier.
+ \author Regis Houssin.
+ \author Laurent Destailleur.
+ \version $Revision$
+
+ Ensemble des fonctions permettant d'accèder à un serveur LDAP.
+*/
+
+class AuthLdap {
+
+
+ /**
+ * Tableau des serveurs (IP addresses ou nom d'hôtes)
+ */
+ var $server;
+ /**
+ * 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;
+ /**
+ * 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;
+
+ // 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
+ *
+ * @param string the ldap server to connect to
+ * @param string the base dn
+ * @param string the server type- current supports OpenLdap and ActiveDirectory
+ * @param string the domain to use when authenticating against Active Directory
+ * @param string the username to authenticate with when searching if anonymous binding is not supported
+ * @param string the password to authenticate with when searching if anonymous binding is not supported
+ */
+ function AuthLdap () {
+ global $conf;
+
+ $this->server = array($conf->global->LDAP_SERVER_HOST, $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 = $sDomain;
+ $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;
+ }
+
+ // 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.
+ */
+ function connect() {
+ foreach ($this->server as $key => $host) {
+ if (ereg('^ldap',$host)) {
+ $this->connection = ldap_connect($host);
+ } else {
+ $this->connection = ldap_connect($host,$this->serverPort);
+ }
+ if ( $this->connection) {
+ $this->setVersion();
+ if ($this->serverType == "activedirectory") {
+ return true;
+ } else {
+ // Connected, now try binding anonymously
+ $this->result=@ldap_bind( $this->connection);
+ }
+ return true;
+ }
+ }
+
+ $this->ldapErrorCode = -1;
+ $this->ldapErrorText = "Unable to connect to any server";
+ return false;
+ }
+
+ /**
+ * 2.1.2 : Simply closes the connection set up earlier.
+ * Returns true if OK, false if there was an error.
+ */
+ function close() {
+ if ( !@ldap_close($this->connection)) {
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $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);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * \brief unbind du serveur ldap.
+ * \param ds
+ * \return bool
+ */
+ function unbind() {
+ if (!$this->result=@ldap_unbind($this->connection)) {
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $this->connection);
+ 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 authBind( $bindDn,$pass) {
+ if ( !$this->result = @ldap_bind( $this->connection,$bindDn,$pass)) {
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $this->connection);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /**
+ * \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.
+ * \param ds
+ * \param version
+ * \return version
+ */
+ function setVersion() {
+ $ldapsetversion = ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $this->ldapProtocolVersion);
+ return $ldapsetversion;
+ }
+
+ // 2.2 Password methods ------------------------------------------------------
+
+ /**
+ * 2.2.1 : 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.
+ */
+ function checkPass( $uname,$pass) {
+ /* Construct the full DN, eg:-
+ ** "uid=username, ou=People, dc=orgname,dc=com"
+ */
+ if ($this->serverType == "activedirectory") {
+ $checkDn = "$uname@$this->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!
+ 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);
+ return false;
+ }
+ }
+
+
+ /**
+ * 2.2.2 : Allows a password to be changed. Note that on most LDAP servers,
+ * a new ACL must be defined giving users the ability to modify their
+ * password attribute (userPassword). Otherwise this will fail.
+ */
+ function changePass( $uname,$oldPass,$newPass) {
+ // builds the appropriate dn, based on whether $this->people and/or $this->group is set
+ if ($this->serverType == "activedirectory") {
+ $checkDn = "$uname@$this->domain";
+ } else {
+ $checkDn = $this->getUserIdentifier() . "=$uname, " . $this->setDn(true);
+ }
+ $this->result = @ldap_bind( $this->connection,$checkDn,$oldPass);
+
+ if ( $this->result) {
+ // Connected OK - Now modify the password...
+ $info["userPassword"] = $newPass;
+ $this->result = @ldap_modify( $this->connection, $checkDn, $info);
+ if ( $this->result) {
+ // Change went OK
+ return true;
+ } else {
+ // Couldn't change password...
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $this->connection);
+ return false;
+ }
+ } else {
+ // Login failed - see checkPass method for common error codes
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $this->connection);
+ return false;
+ }
+ }
+
+
+ /**
+ * 2.2.3 : Returns days until the password will expire.
+ * We have to explicitly state this is what we want returned from the
+ * LDAP server - by default, it will only send back the "basic"
+ * attributes.
+ */
+ function checkPassAge ( $uname) {
+
+ $results[0] = "passwordexpirationtime";
+ // builds the appropriate dn, based on whether $this->people and/or $this->group is set
+ $checkDn = $this->setDn(true);
+ $this->result = @ldap_search( $this->connection,$checkDn,$this->getUserIdentifier()."=$uname",$results);
+
+ if ( !$info=@ldap_get_entries( $this->connection, $this->result)) {
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $this->connection);
+ return false;
+ } else {
+ /* Now work out how many days remaining....
+ ** Yes, it's very verbose code but I left it like this so it can easily
+ ** be modified for your needs.
+ */
+ $date = $info[0]["passwordexpirationtime"][0];
+ $year = substr( $date,0,4);
+ $month = substr( $date,4,2);
+ $day = substr( $date,6,2);
+ $hour = substr( $date,8,2);
+ $min = substr( $date,10,2);
+ $sec = substr( $date,12,2);
+
+ $timestamp = mktime( $hour,$min,$sec,$month,$day,$year);
+ $today = mktime();
+ $diff = $timestamp-$today;
+ return round( ( ( ( $diff/60)/60)/24));
+ }
+ }
+
+ // 2.3 Group methods ---------------------------------------------------------
+
+ /**
+ * 2.3.1 : Checks to see if a user is in a given group. If so, it returns
+ * true, and returns false if the user isn't in the group, or any other
+ * error occurs (eg:- no such user, no group by that name etc.)
+ */
+ function checkGroup ( $uname,$group) {
+ // builds the appropriate dn, based on whether $this->people and/or $this->group is set
+ $checkDn = $this->setDn(false);
+
+ // We need to search for the group in order to get it's entry.
+ $this->result = @ldap_search( $this->connection, $checkDn, "cn=" .$group);
+ $info = @ldap_get_entries( $this->connection, $this->result);
+
+ // Only one entry should be returned(no groups will have the same name)
+ $entry = ldap_first_entry( $this->connection,$this->result);
+
+ if ( !$entry) {
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $this->connection);
+ return false; // Couldn't find the group...
+ }
+ // Get all the member DNs
+ if ( !$values = @ldap_get_values( $this->connection, $entry, "uniqueMember")) {
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $this->connection);
+ return false; // No users in the group
+ }
+
+ foreach ( $values as $key => $value) {
+ /* Loop through all members - see if the uname is there...
+ ** Also check for sub-groups - this allows us to define a group as
+ ** having membership of another group.
+ ** FIXME:- This is pretty ugly code and unoptimised. It takes ages
+ ** to search if you have sub-groups.
+ */
+ list( $cn,$ou) = explode( ",",$value);
+ list( $ou_l,$ou_r) = explode( "=",$ou);
+
+ if ( $this->groups==$ou_r) {
+ list( $cn_l,$cn_r) = explode( "=",$cn);
+ // OK, So we now check the sub-group...
+ if ( $this->checkGroup ( $uname,$cn_r)) {
+ return true;
+ }
+ }
+
+ if ( preg_match( "/$uname/i",$value)) {
+ return true;
+ }
+ }
+ }
+
+ // 2.4 Attribute methods -----------------------------------------------------
+ /**
+ * 2.4.1 : Returns an array containing a set of attribute values.
+ * For most searches, this will just be one row, but sometimes multiple
+ * results are returned (eg:- multiple email addresses)
+ */
+ function getAttribute ( $uname,$attribute) {
+
+ global $conf;
+
+ // builds the appropriate dn, based on whether $this->people and/or $this->group is set
+ //$checkDn = $this->setDn( true);
+ $checkDn = $this->people;
+ $results[0] = $attribute;
+
+ // We need to search for this user in order to get their entry.
+ $this->result = @ldap_search( $this->connection,$checkDn,$this->getUserIdentifier()."=$uname",$results);
+ $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);
+
+ if ( !$entry) {
+ $this->ldapErrorCode = -1;
+ $this->ldapErrorText = "Couldn't find user";
+ return false; // Couldn't find the user...
+ }
+
+ // Get all the member DNs
+ 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
+ }
+
+ // Return an array containing the attributes.
+ return $values;
+ }
+
+ /**
+ * 2.4.2 : Allows an attribute value to be set.
+ * This can only usually be done after an authenticated bind as a
+ * directory manager - otherwise, read/write access will not be granted.
+ */
+ function setAttribute( $uname, $attribute, $value) {
+ // Construct a full DN...
+ // builds the appropriate dn, based on whether $this->people and/or $this->group is set
+ $attrib_dn = $this->getUserIdentifier()."=$uname," . $this->setDn(true);
+
+ $info[$attribute] = $value;
+ // Change attribute
+ $this->result = ldap_modify( $this->connection, $attrib_dn, $info);
+ if ( $this->result) {
+ // Change went OK
+ return true;
+ } else {
+ // Couldn't change password...
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $this->connection);
+ return false;
+ }
+ }
+
+ // 2.5 User methods ----------------------------------------------------------
+ /**
+ * 2.5.1 : Returns an array containing a details of users, sorted by
+ * username. The search criteria is a standard LDAP query - * returns all
+ * users. The $attributeArray variable contains the required user detail field names
+ */
+ function getUsers( $search, $attributeArray) {
+
+ global $conf;
+
+ // builds the appropriate dn, based on whether $this->people and/or $this->group is set
+ //$checkDn = $this->setDn( true);
+ $checkDn = $conf->global->LDAP_USER_DN;
+
+ // Perform the search and get the entry handles
+
+ // if the directory is AD, then bind first with the search user first
+ if ($this->serverType == "activedirectory") {
+ $this->authBind($this->searchUser, $this->searchPassword);
+ }
+
+ $filter = '('.$conf->global->LDAP_FILTER_CONNECTION.'('.$this->getUserIdentifier().'='.$search.'))';
+
+ $this->result = @ldap_search( $this->connection, $checkDn, $filter);
+
+ if (!$this->result)
+ {
+ $this->ldapErrorCode = ldap_errno( $this->connection);
+ $this->ldapErrorText = ldap_error( $this->connection);
+ }
+
+ $info = @ldap_get_entries( $this->connection, $this->result);
+
+ for( $i = 0; $i < $info["count"]; $i++)
+ {
+ // Get the username, and create an array indexed by it...
+ // Modify these as you see fit.
+ $uname = $info[$i][$this->getUserIdentifier()][0];
+
+ // add to the array for each attribute in my list
+ for ( $j = 0; $j < count( $attributeArray); $j++)
+ {
+ if (strtolower($attributeArray[$j]) == "dn")
+ {
+ $userslist["$uname"]["$attributeArray[$j]"] = $info[$i][strtolower($attributeArray[$j])];
+ }
+ else if (strtolower($attributeArray[$j]) == "objectsid")
+ {
+ $objectsid = $this->getObjectSid($uname);
+ $userslist["$uname"]["$attributeArray[$j]"] = $objectsid[0];
+ }
+ else
+ {
+ $userslist["$uname"]["$attributeArray[$j]"] = $info[$i][strtolower($attributeArray[$j])][0];
+ }
+ }
+ }
+
+ if ( !@asort( $userslist)) {
+ /* Sort into alphabetical order. If this fails, it's because there
+ ** were no results returned (array is empty) - so just return false.
+ */
+ $this->ldapErrorCode = -1;
+ $this->ldapErrorText = "No users found matching search criteria ".$search;
+ return false;
+ }
+ return $userslist;
+
+ }
+
+ /**
+ * Récupère le SID de l'utilisateur
+ * ldapuser. le login de l'utilisateur
+ */
+ function getObjectSid($ldapUser)
+ {
+ global $conf;
+
+ $criteria = $this->getUserIdentifier()."=$ldapUser";
+ $justthese = array("objectsid");
+ $checkDn = $conf->global->LDAP_USER_DN;
+
+ $ldapSearchResult = ldap_search($this->connection, $checkDn, $criteria, $justthese);
+
+ $entry = ldap_first_entry($this->connection, $ldapSearchResult);
+ $ldapBinary = ldap_get_values_len ($this->connection, $entry, "objectsid");
+
+ return $ldapBinary;
+ }
+
+
+ // 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) {
+
+ 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;
+ }
+ }
+
+ 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 "samaccountname";
+ } else {
+ return "uid";
+ }
+ }
+
+ /**
+ * \brief permet d'enlever les accents d'une chaine.
+ * \param str
+ * \return string
+ */
+ function dolibarr_ldap_unacc($str)
+ {
+ $stu = ereg_replace("é","e",$str);
+ $stu = ereg_replace("è","e",$stu);
+ $stu = ereg_replace("ê","e",$stu);
+ $stu = ereg_replace("à","a",$stu);
+ $stu = ereg_replace("ç","c",$stu);
+ $stu = ereg_replace("ï","i",$stu);
+ $stu = ereg_replace("ä","a",$stu);
+ return $stu;
+ }
+
+} // End of class
+?>
diff --git a/htdocs/lib/ldap.lib.php b/htdocs/lib/ldap.lib.php
deleted file mode 100644
index 72f4abe0c31..00000000000
--- a/htdocs/lib/ldap.lib.php
+++ /dev/null
@@ -1,163 +0,0 @@
-
- * Copyright (C) 2004 Benoit Mortier
- * Copyright (C) 2005 Regis Houssin
- * Copyright (C) 2006 Laurent Destailleur
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * or see http://www.gnu.org/
- *
- * $Id$
- * $Source$
- */
-
-/**
- \file htdocs/lib/ldap.lib.php
- \brief Librairie contenant les fonctions pour accèder au serveur ldap.
- \author Rodolphe Quiedeville.
- \author Benoit Mortier.
- \version $Revision$
-
- Ensemble des fonctions permettant d'accèder à un serveur LDAP.
-*/
-
-class Ldap
-{
- var $err; // erreur ldap
-
-
- /**
- * \brief Constructeur de la classe
- */
- function Ldap()
- {
- $this->err = "";
- }
-
-
-/**
- \brief Ouverture d'une connection vers le serveur LDAP
- \return resource
-*/
-function dolibarr_ldap_connect()
-{
- global $conf;
-
- if (ereg('^ldap',$conf->global->LDAP_SERVER_HOST))
- {
- // ex url: ldaps://ldap.example.com/
- $ldapconnect = ldap_connect($conf->global->LDAP_SERVER_HOST);
- }
- else
- {
- // ex serveur: localhost
- // ex port: 389
- $ldapconnect = ldap_connect($conf->global->LDAP_SERVER_HOST,$conf->global->LDAP_SERVER_PORT);
- }
-
- if ($ldapconnect)
- {
- ldap_set_option($ldapconnect, LDAP_OPT_PROTOCOL_VERSION, $conf->global->LDAP_SERVER_PROTOCOLVERSION);
- }
- return $ldapconnect;
-}
-
-
-/**
- \brief Se connecte au serveur LDAP avec user et mot de passe
- \param ds
- \return bool
-*/
-function dolibarr_ldap_bind($ds)
-{
- global $conf;
-
- if (defined("LDAP_ADMIN_PASS") && $conf->global->LDAP_ADMIN_DN && $conf->global->LDAP_ADMIN_PASS)
- {
- $ldapbind = @ldap_bind($ds, $conf->global->LDAP_ADMIN_DN, $conf->global->LDAP_ADMIN_PASS);
- }
-
- if ($ldapbind)
- {
- return $ldapbind;
- }
- else
- {
- $this->err = ldap_error($ds);
- }
-}
-
-/**
- \brief unbind du serveur ldap.
- \param ds
- \return bool
-*/
-function dolibarr_ldap_unbind($ds)
-{
- $ldapunbind = @ldap_unbind($ds);
-
- return $ldapunbind;
-}
-
-/**
- \brief verification de la version du serveur ldap.
- \param ds
- \return version
-*/
-function dolibarr_ldap_getversion($ds)
-{
- global $conf;
-
- $version = 0;
-
- ldap_get_option($ds, LDAP_OPT_PROTOCOL_VERSION, $version);
-
- return $version;
-}
-
-/**
- \brief changement de la version du serveur ldap.
- \param ds
- \param version
- \return version
-*/
-function dolibarr_ldap_setversion($ds,$version)
-{
- global $conf;
-
- $ldapsetversion = ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $version);
-
- return $ldapsetversion;
-}
-
-/**
- \brief permet d'enlever les accents d'une chaine.
- \param str
- \return string
-*/
-function dolibarr_ldap_unacc($str)
-{
- $stu = ereg_replace("é","e",$str);
- $stu = ereg_replace("è","e",$stu);
- $stu = ereg_replace("ê","e",$stu);
- $stu = ereg_replace("à","a",$stu);
- $stu = ereg_replace("ç","c",$stu);
- $stu = ereg_replace("ï","i",$stu);
- $stu = ereg_replace("ä","a",$stu);
- return $stu;
-}
-}
-
-?>
diff --git a/htdocs/user.class.php b/htdocs/user.class.php
index 88ad673e225..c45e8e7aa07 100644
--- a/htdocs/user.class.php
+++ b/htdocs/user.class.php
@@ -49,6 +49,7 @@ class User
var $db;
var $id;
+ var $ldap_sid;
var $fullname;
var $nom;
var $prenom;
@@ -102,7 +103,7 @@ class User
{
// Recupere utilisateur
$sql = "SELECT u.rowid, u.name, u.firstname, u.email, u.office_phone, u.office_fax, u.user_mobile, u.code, u.admin, u.login, u.pass, u.webcal_login, u.note,";
- $sql.= " u.fk_societe, u.fk_socpeople, ";
+ $sql.= " u.fk_societe, u.fk_socpeople, u.ldap_sid,";
$sql.= " ".$this->db->pdate("u.datec")." as datec, ".$this->db->pdate("u.tms")." as datem,";
$sql.= " ".$this->db->pdate("u.datelastaccess")." as datel";
$sql.= " FROM ".MAIN_DB_PREFIX."user as u";
@@ -122,6 +123,7 @@ class User
if ($obj)
{
$this->id = $obj->rowid;
+ $this->ldap_sid = $obj->ldap_sid;
$this->nom = stripslashes($obj->name);
$this->prenom = stripslashes($obj->firstname);
@@ -129,9 +131,9 @@ class User
$this->code = $obj->code;
$this->login = $obj->login;
$this->pass = $obj->pass;
- $this->office_phone = $obj->office_phone;
- $this->office_fax = $obj->office_fax;
- $this->user_mobile = $obj->user_mobile;
+ $this->office_phone = $obj->office_phone;
+ $this->office_fax = $obj->office_fax;
+ $this->user_mobile = $obj->user_mobile;
$this->email = $obj->email;
$this->admin = $obj->admin;
$this->contact_id = $obj->fk_socpeople;
@@ -574,7 +576,7 @@ class User
}
else
{
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."user (datec,login) VALUES(now(),'".addslashes($this->login)."')";
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."user (datec,login,ldap_sid) VALUES(now(),'".addslashes($this->login)."','".$this->ldap_sid."')";
$result=$this->db->query($sql);
if ($result)
diff --git a/htdocs/user/fiche.php b/htdocs/user/fiche.php
index 6fee56868af..f405bb4ee96 100644
--- a/htdocs/user/fiche.php
+++ b/htdocs/user/fiche.php
@@ -32,6 +32,7 @@
require("./pre.inc.php");
require_once(DOL_DOCUMENT_ROOT."/contact.class.php");
+require_once(DOL_DOCUMENT_ROOT."/lib/authldap.lib.php");
// Defini si peux creer un utilisateur ou gerer groupe sur un utilisateur
@@ -124,12 +125,13 @@ if ($_POST["action"] == 'add' && $canadduser)
$edituser->prenom = trim($_POST["prenom"]);
$edituser->login = trim($_POST["login"]);
$edituser->admin = trim($_POST["admin"]);
- $edituser->office_phone = trim($_POST["office_phone"]);
- $edituser->office_fax = trim($_POST["office_fax"]);
- $edituser->user_mobile = trim($_POST["user_mobile"]);
+ $edituser->office_phone = trim($_POST["office_phone"]);
+ $edituser->office_fax = trim($_POST["office_fax"]);
+ $edituser->user_mobile = trim($_POST["user_mobile"]);
$edituser->email = trim($_POST["email"]);
$edituser->webcal_login = trim($_POST["webcal_login"]);
$edituser->note = trim($_POST["note"]);
+ $edituser->ldap_sid = trim($_POST["ldap_sid"]);
$db->begin();
@@ -295,7 +297,7 @@ if ((($_POST["action"] == 'confirm_password' && $_POST["confirm"] == 'yes')
llxHeader('',$langs->trans("UserCard"));
-if ($action == 'create')
+if (($action == 'create') || ($action == 'adduserldap'))
{
/* ************************************************************************** */
/* */
@@ -307,33 +309,154 @@ if ($action == 'create')
print " ";
if ($message) { print $message.' '; }
+
+ /*
+ * ajout utilisateur ldap
+ */
+ if ($conf->ldap->enabled)
+ {
+ if ($conf->global->LDAP_SERVER_HOST && $conf->global->LDAP_ADMIN_DN && $conf->global->LDAP_ADMIN_PASS)
+ {
+ $ldap = new AuthLdap();
+
+ if ($ldap->connect())
+ {
+ $justthese = array( "sn", "givenname", "samaccountname");
+ $ldapusers = $ldap->getUsers('*', $justthese);
+
+ if ($ldapusers)
+ {
+ $html = new Form($db);
+
+ foreach ($ldapusers as $key => $ldapuser)
+ {
+ if($ldapuser["sn"] != "")
+ $liste[$ldapuser["samaccountname"]] = utf8_decode($ldapuser["sn"])." ".utf8_decode($ldapuser["givenname"]);
+ }
+
+ print '';
+ print " ";
+ }
+
+ if ($action == 'adduserldap')
+ {
+
+
+ $selecteduser = $_POST['users'];
+ $justthese = array( "samaccountname",
+ "sn",
+ "givenname",
+ "mail",
+ "telephonenumber",
+ "facsimiletelephonenumber",
+ "mobile",
+ "objectsid");
+
+ $selectedUser = $ldap->getUsers($selecteduser, $justthese);
+
+ if ($selectedUser)
+ {
+ foreach ($selectedUser as $key => $attribute)
+ {
+ $ldap_nom = utf8_decode($attribute["sn"]?$attribute["sn"]:'');
+ $ldap_prenom = utf8_decode($attribute["givenname"]?$attribute["givenname"]:'');
+ $ldap_login = utf8_decode($attribute["samaccountname"]?$attribute["samaccountname"]:'');
+ $ldap_phone = utf8_decode($attribute["telephonenumber"]?$attribute["telephonenumber"]:'');
+ $ldap_fax = utf8_decode($attribute["facsimiletelephonenumber"]?$attribute["facsimiletelephonenumber"]:'');
+ $ldap_mobile = utf8_decode($attribute["mobile"]?$attribute["mobile"]:'');
+ $ldap_mail = utf8_decode($attribute["mail"]?$attribute["mail"]:'');
+ $ldap_SID = bin2hex($attribute["objectsid"]);
+ }
+ }
+ }
+ }
+ else
+ {
+ print $ldap->ldapErrorCode;
+ print $ldap->ldapErrorText;
+ }
+ if (!$ldap->close())
+ {
+ print $ldap->ldapErrorCode;
+ print $ldap->ldapErrorText;
+ }
+ }
+ }
print '