[dev] hook in the Auth class [PATCH]
Etienne Goyer
etienne.goyer at linuxquebec.com
Tue Sep 30 08:40:57 PDT 2003
You asked for it !
I really hope this get commited. I think my example functions are
pretty spiffy and could actually be very useful in some situation.
Feedback welcome.
On Tue, Sep 30, 2003 at 12:34:47PM +0100, Nuno Loureiro wrote:
>
> It might be of some use to me too...
> Pleae submit the patch to the list when ready...
>
> On Sun, 2003-09-28 at 21:40, Etienne Goyer wrote:
> > Hi list,
> >
> > I am requesting comments on a feature I would like to implement. I
> > would like to add two hooks to the Auth class authenticate() function.
> > I suggest calling them _authenticate_hook_pre and
> > _authenticate_hook_post. If either of these function return false,
> > authentication fail. There could be only one of these function, but two
> > would be more flexible IMHO.
> >
> > The reason I need these is that, although my users are authenticated
> > thru IMP (IMAP), I would like to consult an LDAP directory for
> > membership to a specific group before giving them access to Horde. I
> > suppose similar requirement to mine could also happen to other people.
> >
> > If that feature seem interesting to maintainer, I would code and send a
> > patch in the coming days.
> >
> > Thanks !
> >
> > --
> > Etienne Goyer Linux Québec Technologies Inc.
> > http://www.LinuxQuebec.com etienne.goyer at linuxquebec.com
> --
> Nuno Loureiro <nuno at co.sapo.pt>
> PTM.com - http://www.sapo.pt/
> PGP fingerprint = 8A32 5174 E80C 2D40 9075 405E C107 6592 054A 4D05
>
>
> --
> Horde developers mailing list
> Frequently Asked Questions: http://horde.org/faq/
> To unsubscribe, mail: dev-unsubscribe at lists.horde.org
--
Etienne Goyer Linux Québec Technologies Inc.
http://www.LinuxQuebec.com etienne.goyer at linuxquebec.com
-------------- next part --------------
--- lib/Auth.php.orig Mon Sep 29 16:57:37 2003
+++ lib/Auth.php Tue Sep 30 10:14:27 2003
@@ -170,19 +170,38 @@
global $conf;
$userID = trim($userID);
+ $auth = false;
+
+ if (!empty($conf['hooks']['preauthenticate'])) {
+ @include_once HORDE_BASE . '/config/hooks.php';
+ if (function_exists('_horde_hook_preauthenticate')) {
+ if (!call_user_func('_horde_hook_preauthenticate', $userID, $credentials, $realm)) {
+ return false;
+ }
+ }
+ }
if ($this->_authenticate($userID, $credentials)) {
if ($login) {
$this->clearAuth();
$this->setAuth($userID, $credentials, $realm);
- return true;
+ $auth = true;
} elseif (empty($conf['auth']['checkip']) ||
($_SESSION['__auth']['remote_addr'] == $_SERVER['REMOTE_ADDR'])) {
- return true;
+ $auth = true;
}
}
+
+ if (!empty($conf['hooks']['postauthenticate'])) {
+ @include_once HORDE_BASE . '/config/hooks.php';
+ if (function_exists('_horde_hook_postauthenticate')) {
+ if (!call_user_func('_horde_hook_postauthenticate', $userID, $credentials, $realm)) {
+ return false;
+ }
+ }
+ }
- return false;
+ return $auth;
}
/**
--- config/conf.php.dist.orig Tue Sep 30 11:28:01 2003
+++ config/conf.php.dist Tue Sep 30 11:31:27 2003
@@ -509,3 +509,13 @@
// example when showing name lists to the user.
// There are examples for such functions in horde/config/hooks.php.dist.
$conf['hooks']['username'] = false;
+
+// If this is set to true and the function _horde_hook_preauthenticate() return
+// false, authentication will fail.
+// There are examples for such functions in horde/config/hooks.php.dist.
+$conf['hooks']['preauthenticate'] = false;
+
+// If this is set to true and the function _horde_hook_postauthenticate() return
+// false, authentication will fail.
+// There are examples for such functions in horde/config/hooks.php.dist.
+$conf['hooks']['postauthenticate'] = false;
--- config/hooks.php.dist.orig Tue Sep 30 11:18:56 2003
+++ config/hooks.php.dist Tue Sep 30 11:27:36 2003
@@ -203,6 +203,59 @@
}
}
+// Here is an example _horde_hook_preauthenticate that make Horde respect the
+// Unix convention of not allowing login when a file named /etc/nologin exist.
+// This function get passed the username, credential and realm information but
+// they are not used in this example.
+if (!function_exists('_horde_hook_preauthenticate')) {
+ function _horde_hook_preauthenticate($userID, $credential, $realm)
+ {
+ return !file_exists('/etc/nologin');
+ }
+}
+
+// Here is an example of validating the user's right to login to Horde by
+// consulting group membership in an LDAP directory. That way, if your Horde
+// installation is configured to authenticate against IMP which in turn
+// authenticate via IMAP, it is still possible to limit access to Horde by group
+// membership. The following example had been made with an MS Active Directory
+// in mind. Note that if the LDAP directory is unavailable or some other error
+// occur, authentication will fail.
+if (!function_exists('_horde_hook_postauthenticate')) {
+ function _horde_hook_postauthenticate($userID, $credential, $realm)
+ {
+ $ldapServer = 'ad.example.com';
+ $ldapPort = '389';
+ // Note that credential is sent plain-text in this case, so don't use
+ // privileged account here or setup SSL (by using port 636 above).
+ $binddn = "cn=WithoutPrivilege,dc=ulaval-dev,dc=ca";
+ $bindpw = "Remember this is sent in the clear unless SSL is used";
+ $searchBase = 'ou=People,dc=example,dc=com';
+ $userAttr = "sAMAccountName"; // Attribute to match $userID against in search
+ $groupAttr = "memberof"; // Group membership attribute, need to be all lowercase
+ $groupdn = "cn=HordeUser,ou=People,dc=example,dc=com"; // Attribute to check for right to use Horde
+ $ret = true;
+
+ $ds = @ldap_connect($ldapServer, $ldapPort);
+
+ if (@ldap_bind($ds, $binddn, $bindpw)) {
+ $searchResult = @ldap_search($ds, $searchBase, $userAttr . '=' . $userID, array($groupAttr), 0, 1, 5);
+ if ($information = @ldap_get_entries($ds, $searchResult)) {
+ $pattern = '/' . $groupdn . '/i'; // make pattern case-insensitive
+ foreach ($information[0][$groupAttr] as $group) {
+ if (preg_match($pattern, $group)) {
+ $ret = true;
+ break;
+ }
+ }
+ }
+ }
+
+ ldap_close($ds);
+ return $ret;
+ }
+}
+
// Here is an example fullname hook function to set the fullname from the GECOS
// information in the passwd file.
if (!function_exists('_prefs_hook_fullname')) {
More information about the dev
mailing list