Revision: 1609
http://mrbs.svn.sourceforge.net/mrbs/?rev=1609&view=rev
Author: jberanek
Date: 2010-11-17 18:54:36 +0000 (Wed, 17 Nov 2010)
Log Message:
-----------
* Introduced the ability to get a user's email address from LDAP if
the system is configured to use LDAP for authentication. Adds the
config variables: $ldap_get_user_email, $ldap_email_attrib. As part of
this work also added two new LDAP config variables:
$ldap_unbind_between_attempts and $ldap_debug.
Modified Paths:
--------------
mrbs/trunk/web/auth_ldap.inc
mrbs/trunk/web/functions_mail.inc
mrbs/trunk/web/systemdefaults.inc.php
Modified: mrbs/trunk/web/auth_ldap.inc
===================================================================
--- mrbs/trunk/web/auth_ldap.inc 2010-11-17 17:59:26 UTC (rev 1608)
+++ mrbs/trunk/web/auth_ldap.inc 2010-11-17 18:54:36 UTC (rev 1609)
@@ -8,18 +8,21 @@
$auth['session']='http';
}
-/* authValidateUser($user, $pass)
+/* authLdapAction($callback, $user, &$object)
*
- * Checks if the specified username/password pair are valid
+ * Connects/binds to all configured LDAP servers/base DNs and
+ * then performs a callback, passing the LDAP object, $base_dn,
+ * user DN (in $dn), $user and a generic object $object
+ *
+ * $callback - The callback function
+ * $user - The user name
+ * &$object - Reference to the generic object, type defined by caller
*
- * $user - The user name
- * $pass - The password
- *
* Returns:
* 0 - The pair are invalid or do not exist
* non-zero - The pair are valid
*/
-function authValidateUser($user, $pass)
+function authLdapAction($callback, $user, &$object)
{
global $auth;
global $ldap_host;
@@ -28,7 +31,6 @@
global $ldap_tls;
global $ldap_base_dn;
global $ldap_user_attrib;
- global $ldap_filter;
global $ldap_dn_search_attrib;
global $ldap_dn_search_dn;
global $ldap_dn_search_password;
@@ -42,14 +44,6 @@
$all_ldap_base_dn = array();
$all_ldap_user_attrib = array();
- // Check if we do not have a username/password
- // User can always bind to LDAP anonymously with empty password,
- // therefore we need to block empty password here...
- if (!isset($user) || !isset($pass) || strlen($pass)==0)
- {
- return 0;
- }
-
// Check that if there is an array of hosts and an array of ports
// then the number of each must be the same or the authenication
// is forced to fail.
@@ -100,6 +94,8 @@
// Check that connection was established
if ($ldap)
{
+ authLdapDebug("authLdapAction: Got LDAP connection");
+
if ($ldap_v3)
{
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
@@ -113,6 +109,7 @@
// or fail
foreach ( $all_ldap_base_dn as $idx => $base_dn)
{
+ authLdapDebug("authLdapAction: start of foreach $base_dn");
if (isset($ldap_dn_search_attrib))
{
if (isset($ldap_dn_search_dn) &&
@@ -127,6 +124,7 @@
// Anonymous bind
$res = @ldap_bind($ldap);
}
+ authLdapDebug("authLdapAction: Result of initial bind is $res");
if ($res)
{
@@ -136,10 +134,19 @@
if (@ldap_count_entries($ldap, $res) == 1)
{
+ authLdapDebug("authLdapAction: Found one entry using ".
+ "\$ldap_dn_search_attrib");
$entries = ldap_get_entries($ldap, $res);
$dn = $entries[0]["dn"];
$user_search = "distinguishedName=" . $dn;
}
+ else
+ {
+ authLdapDebug("authLdapAction: Didn't find entry using ".
+ "\$ldap_dn_search_attrib");
+ }
+ authLdapDebug("authLdapAction: base_dn $base_dn user $user ".
+ "dn $dn");
}
}
else
@@ -147,36 +154,189 @@
// construct dn for user
$user_search = $all_ldap_user_attrib[$idx] . "=" . $user;
$dn = $user_search . "," . $base_dn;
+
+ authLdapDebug("authLdapAction: Constructed dn $dn and ".
+ "user_search $user_search using ".
+ "\$ldap_user_attrib");
}
- // try an authenticated bind
- // use this to confirm that the user/password pair
- if ($dn && @ldap_bind($ldap, $dn, $pass))
+ $res = $callback($ldap, $base_dn, $dn, $user_search, $user, $object);
+ if ($res)
{
- // however if there is a filter check that the
- // user is part of the group defined by the filter
- if (! $ldap_filter)
- {
- @ldap_unbind($ldap);
- return 1;
- }
- else
- {
- $res = @ldap_search($ldap,
- $base_dn,
- "(&($user_search)($ldap_filter))",
- array()
- );
- if (@ldap_count_entries($ldap, $res) > 0)
- {
- @ldap_unbind($ldap);
- return 1;
- }
- }
+ return $res;
}
+
+ } // foreach
+
+ @ldap_unbind($ldap);
+ } // if ($ldap)
+}
+
+
+/* authLdapGetEmail($user)
+ *
+ * Gets the email address of the user from LDAP
+ *
+ * $user - The user name
+ *
+ * Returns:
+ * The user's email address or ''
+ */
+function authLdapGetEmail($user)
+{
+ $email = '';
+ $object = array();
+
+ $res = authLdapAction("authLdapGetEmailCallback", $user, $object);
+
+ if ($res)
+ {
+ $email = $object['email'];
+ }
+ return $email;
+}
+
+
+/* authValidateUserCallback(&$ldap, $base_dn, $dn, $user_search,
+ $user, &$object)
+ *
+ * Checks if the specified username/password pair are valid
+ *
+ * &$ldap - Reference to the LDAP object
+ * $base_dn - The base DN
+ * $dn - The user's DN
+ * $user_search - The LDAP filter to find the user
+ * $user - The user name
+ * &$object - Reference to the generic object
+ *
+ * Returns:
+ * 0 - Didn't find a user
+ * non-zero - Found a user
+ */
+function authLdapGetEmailCallback(&$ldap, $base_dn, $dn, $user_search,
+ $user, &$object)
+{
+ global $ldap_email_attrib;
+
+ authLdapDebug("authLdapGetEmailCallback: base_dn $base_dn dn $dn ".
+ "user_search $user_search user $user");
+
+ if ($ldap && $base_dn && $dn && $user_search)
+ {
+ $res = @ldap_search($ldap,
+ $base_dn,
+ "($user_search)",
+ array($ldap_email_attrib)
+ );
+ if (@ldap_count_entries($ldap, $res) > 0)
+ {
+ authLdapDebug("authLdapGetEmailCallback: search successful");
+ $entries = ldap_get_entries($ldap, $res);
+ $object['email'] = $entries[0][$ldap_email_attrib][0];
+
+ authLdapDebug("authLdapGetEmailCallback: email is '".
+ $object['email']."'");
+
+ return 1;
}
+ }
+ return 0;
+}
+
+/* authValidateUser($user, $pass)
+ *
+ * Checks if the specified username/password pair are valid
+ *
+ * $user - The user name
+ * $pass - The password
+ *
+ * Returns:
+ * 0 - The pair are invalid or do not exist
+ * non-zero - The pair are valid
+ */
+function authValidateUser($user, $pass)
+{
+ // Check if we do not have a username/password
+ // User can always bind to LDAP anonymously with empty password,
+ // therefore we need to block empty password here...
+ if (!isset($user) || !isset($pass) || strlen($pass)==0)
+ {
+ authLdapDebug("Empty username or password passed");
+ return 0;
+ }
+
+ $object = array();
+ $object['pass'] = $pass;
+
+ return authLdapAction("authValidateUserCallback", $user, $object);
+}
+
+
+/* authValidateUserCallback(&$ldap, $base_dn, $dn, $user_search,
+ $user, &$object)
+ *
+ * Checks if the specified username/password pair are valid
+ *
+ * &$ldap - Reference to the LDAP object
+ * $base_dn - The base DN
+ * $dn - The user's DN
+ * $user_search - The LDAP filter to find the user
+ * $user - The user name
+ * &$object - Reference to the generic object
+ *
+ * Returns:
+ * 0 - Didn't find a user
+ * non-zero - Found a user
+ */
+function authValidateUserCallback(&$ldap, $base_dn, $dn, $user_search,
+ $user, &$object)
+{
+ global $ldap_filter;
+
+ authLdapDebug("authValidateUserCallback: base_dn $base_dn dn $dn user
$user");
+
+ $pass = $object['pass'];
+
+ // try an authenticated bind
+ // use this to confirm that the user/password pair
+ if ($dn && @ldap_bind($ldap, $dn, $pass))
+ {
+ // however if there is a filter check that the
+ // user is part of the group defined by the filter
+ if (! $ldap_filter)
+ {
+ authLdapDebug("authValidateUserCallback: Successful authenticated ".
+ "bind with no $ldap_filter");
+ return 1;
+ }
+ else
+ {
+ authLdapDebug("authValidateUserCallback: Successful authenticated ".
+ "bind checking $ldap_filter");
+
+ $res = @ldap_search($ldap,
+ $base_dn,
+ "(&($user_search)($ldap_filter))",
+ array()
+ );
+ if (@ldap_count_entries($ldap, $res) > 0)
+ {
+ authLdapDebug("authValidateUserCallback: Found entry with filter");
+ return 1;
+ }
+ authLdapDebug("authValidateUserCallback: No entry found with filter");
+ }
+ }
+ else
+ {
+ authLdapDebug("authValidateUserCallback: Bind to $dn failed");
+ }
+
+ if ($ldap_unbind_between_attempts)
+ {
@ldap_unbind($ldap);
}
+
// return failure if no connection is established
return 0;
}
@@ -213,4 +373,20 @@
return 1;
}
+/* authLdapDebug($message)
+ *
+ * Output LDAP debugging, if the configuration variable
+ * $ldap_debug is true.
+ *
+ */
+function authLdapDebug($message)
+{
+ global $ldap_debug;
+
+ if ($ldap_debug)
+ {
+ error_log($message);
+ }
+}
+
?>
Modified: mrbs/trunk/web/functions_mail.inc
===================================================================
--- mrbs/trunk/web/functions_mail.inc 2010-11-17 17:59:26 UTC (rev 1608)
+++ mrbs/trunk/web/functions_mail.inc 2010-11-17 18:54:36 UTC (rev 1609)
@@ -196,7 +196,7 @@
// returns an empty string in the event of an error
function get_email_address($user)
{
- global $mail_settings, $auth, $tbl_users;
+ global $mail_settings, $auth, $tbl_users, $ldap_get_user_email;
if ('db' == $auth['type'])
{
@@ -209,6 +209,10 @@
$email = "";
}
}
+ else if (('ldap' == $auth['type']) && $ldap_get_user_email)
+ {
+ $email = authLdapGetEmail($user);
+ }
else
{
$email = str_replace($mail_settings['username_suffix'], '', $user);
Modified: mrbs/trunk/web/systemdefaults.inc.php
===================================================================
--- mrbs/trunk/web/systemdefaults.inc.php 2010-11-17 17:59:26 UTC (rev
1608)
+++ mrbs/trunk/web/systemdefaults.inc.php 2010-11-17 18:54:36 UTC (rev
1609)
@@ -657,6 +657,20 @@
// they are a valid user of mrbs.
//$ldap_filter = "mrbsuser=y";
+// Set to TRUE to tell MRBS to look up a user's email address in LDAP.
+// Utilises $ldap_email_attrib below
+$ldap_get_user_email = FALSE;
+// The LDAP attribute which holds a user's email address
+$ldap_email_attrib = 'mail';
+
+// Set to TRUE if you want MRBS to call ldap_unbind() between successive
+// attempts to bind. Unbinding while still connected upsets some
+// LDAP servers
+$ldap_unbind_between_attempts = FALSE;
+
+// Output debugging information for LDAP actions
+$ldap_debug = FALSE;
+
// 'auth_imap' configuration settings
// See AUTHENTICATION for details of how check against multiple servers
// Where is the IMAP server
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Beautiful is writing same markup. Internet Explorer 9 supports
standards for HTML5, CSS3, SVG 1.1, ECMAScript5, and DOM L2 & L3.
Spend less time writing and rewriting code and more time creating great
experiences on the web. Be a part of the beta today
http://p.sf.net/sfu/msIE9-sfdev2dev
_______________________________________________
Mrbs-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mrbs-commits