diff options
-rw-r--r-- | LdapAuth.php | 104 | ||||
-rw-r--r-- | README | 17 | ||||
-rw-r--r-- | auth_ldap.php | 65 | ||||
-rw-r--r-- | manifest.xml | 18 |
4 files changed, 204 insertions, 0 deletions
diff --git a/LdapAuth.php b/LdapAuth.php new file mode 100644 index 0000000..12cebe7 --- /dev/null +++ b/LdapAuth.php @@ -0,0 +1,104 @@ +<?php + +/** + * LdapAuth.php + * Authenticate user from OpenLDAP. + * @author Filipp Lepalaan <filipp@mac.com> + * 15.10.2009 + */ + +class LdapAuth +{ + /** + * @param $ldap_server [string] Address of LDAP server + * @param $bas_dn [string] search base for the LDAP search (eg. dc=server,dc=example,dc=com) + */ + public function __construct($ldap_server, $base_dn) + { + $this->ds = ldap_connect($ldap_server) or exit("LDAP connection failed"); + $this->base_dn = $base_dn; + return $this; + } + + /** + * @return false on error, the user array otherwise + * @param $username [string] user name + * @param $password [string] clear text password + */ + public function auth($username, $password) + { + if (empty($username) || empty($password)) { + print("Sorry, empty names and passwords are not allowed"); + return false; + } + + $out = array(); + $groups = array(); + + if (!function_exists("ldap_connect")) { + print("Sorry, but your PHP lacks LDAP support.\n"); + return false; + } + + ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_set_option($this->ds, LDAP_OPT_NETWORK_TIMEOUT, 10); + + $base_dn = $this->base_dn; + $result = ldap_search($this->ds, "cn=users,{$base_dn}", "uid={$username}", + array("cn", "uid", "mail", "description") + ); + + if (!$result) { + printf("LDAP connection failed: %s\n", ldap_error($this->ds)); + return false; + } + + /* Connected to server, find user DN */ + $info = ldap_get_entries($this->ds, $result); + $user = $info[0]; + $user_dn = $user['dn']; + $user_id = $user['uid'][0]; + + /* Remove the count from the list of addresses */ + array_shift($user['mail']); + array_shift($user['description']); + + /* Authenticate */ + $r = ldap_bind($this->ds, $user_dn, $password); + + if (!$r) { + $ec = ldap_errno($this->ds); + // 53 = "Server is unwilling" ie "correct user but bad pw" + $error = ($ec == 53) ? "Incorrect user name or password\n" : ldap_error($this->ds); + print($error); + return false; + } + + /* Fetch all groups the user belongs to */ + $result = ldap_search($this->ds, "cn=groups,{$base_dn}", "memberuid={$user_id}", array('cn')); + $result = ldap_get_entries($this->ds, $result); + + unset($result['count']); // First is just "count" + + foreach($result as $g) { + $groups[] = $g['cn'][0]; + } + + /* Done - close connection and unbind */ + ldap_unbind($this->ds); + + return array( + 'id' => $user_id, + 'mail' => $user['mail'], + 'groups' => $groups, + 'fullname' => $user['cn'][0], + 'description' => $user['description'] + ); + + return false; + + } + +} + +?>
\ No newline at end of file @@ -0,0 +1,17 @@ +This PunBB extension allows your forum to authenticate against an OpenLDAP server. + +##Installation instructions + +* Drop auth_ldap into your punbb/extensions folder +* Edit auth_ldap/auth_ldap.php and modify the server and basedn variables to your environment +* Open http://yourserver/punbb/admin/extensions.php?section=manage and install the extension +* Log in using an LDAP account + +##Notes +* After installing this, LDAP users always get priority (the check is done before the built-in authentication). +This means that a local user with the same name as an LDAP user will have their password overwritten. + +##Bugs + +* Uninstalling doesn't delete the LDAP users. +* The realname is not set from LDAP (add_user() doesn't support it) diff --git a/auth_ldap.php b/auth_ldap.php new file mode 100644 index 0000000..dce8790 --- /dev/null +++ b/auth_ldap.php @@ -0,0 +1,65 @@ +<?php + +/** + * auth_ldap.php + * @version 18.10.2009 + * @author Filipp Lepalaan <filipp@mac.com> + */ + +$ldap_server = "example.com"; +$ldap_basedn = "dc=server,dc=example,dc=com"; + + +/* That's all you should have to change */ + +require "LdapAuth.php"; + +$la = new LdapAuth($ldap_server, $ldap_basedn); +$ldap_user = $la->auth($form_username, $form_password); + +/* User found in LDAP */ +if ($ldap_user != false) +{ + $sql = sprintf("SELECT id FROM `users` WHERE username = '%s'", $forum_db->escape($form_username)); + $row = $forum_db->query($sql)->fetch_row(); + + if (!empty($row)) { + /* LDAP password has priority */ + $sql = sprintf("UPDATE `users` SET password = '%s' WHERE id = %d", $forum_db->escape($password_hash), $row[0]['id']); + $forum_db->query($sql); + } + else { + /* Valid LDAP user not in PunBB, so let's add them */ + $initial_group_id = ($forum_config['o_regs_verify'] == '0') ? $forum_config['o_default_user_group'] : FORUM_UNVERIFIED; + $salt = random_key(12); + $password_hash = forum_hash($password1, $salt); + + /* Insert the new user into the database. Shamelessly ripped from register.php */ + $user_info = array( + 'username' => $ldap_user['id'], + 'group_id' => $initial_group_id, + 'salt' => $salt, + 'password' => $password1, + 'password_hash' => $password_hash, + 'email' => $ldap_user['mail'][0], + 'email_setting' => $forum_config['o_default_email_setting'], + 'timezone' => $_POST['timezone'], + 'dst' => isset($_POST['dst']) ? '1' : '0', + 'language' => $language, + 'style' => $forum_config['o_default_style'], + 'registered' => time(), + 'registration_ip' => get_remote_address(), + 'activate_key' => ($forum_config['o_regs_verify'] == '1') ? '\''.random_key(8, true).'\'' : 'NULL', + 'require_verification' => ($forum_config['o_regs_verify'] == '1'), + 'notify_admins' => ($forum_config['o_regs_report'] == '1') + ); + + add_user($user_info, $new_uid); + + } + +} + +/* End fliphack */ + +?>
\ No newline at end of file diff --git a/manifest.xml b/manifest.xml new file mode 100644 index 0000000..d6d90fc --- /dev/null +++ b/manifest.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<extension engine="1.0"> + <id>auth_ldap</id> + <title>LDAP authentication module</title> + <version>0.1</version> + <description>Enables PunBB to authenticate against LDAP</description> + <author>Filipp Lepalaan</author> + + <minversion>1.3dev</minversion> + <maxtestedon>1.3</maxtestedon> + + <hooks> + <hook id="li_login_form_submitted"><![CDATA[ + require_once $ext_info['path'].'/auth_ldap.php'; + ]]> + </hook> + </hooks> +</extension> |