From 874b81c1c95265f1792f1763a986a410184b336c Mon Sep 17 00:00:00 2001 From: Andrew McMillan Date: Thu, 30 Dec 2010 12:29:51 +1300 Subject: [PATCH] IMAP PAM authentication from Oliver Schulze Signed-off-by: Andrew McMillan --- config/imap_pam_conf_php.txt | 11 ++++ inc/drivers_imap_pam.php | 110 +++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 config/imap_pam_conf_php.txt create mode 100644 inc/drivers_imap_pam.php diff --git a/config/imap_pam_conf_php.txt b/config/imap_pam_conf_php.txt new file mode 100644 index 00000000..a4e026f4 --- /dev/null +++ b/config/imap_pam_conf_php.txt @@ -0,0 +1,11 @@ +/** + * Authentication against IMAP using the imap_open function. + */ +$c->authenticate_hook['call'] = 'IMAP_PAM_check'; +$c->authenticate_hook['config'] = array( + 'imap_url' => '{localhost:993/imap/ssl/novalidate-cert}', + 'email_base' => 'example.com' +); + +include('drivers_imap_pam.php'); + diff --git a/inc/drivers_imap_pam.php b/inc/drivers_imap_pam.php new file mode 100644 index 00000000..7c6daec8 --- /dev/null +++ b/inc/drivers_imap_pam.php @@ -0,0 +1,110 @@ + +* @copyright Based on Eric Seigne script drivers_squid_pam.php +* @license http://gnu.org/copyleft/gpl.html GNU GPL v2 +*/ + +require_once("auth-functions.php"); + +class imapPamDrivers +{ + /**#@+ + * @access private + */ + + /**#@-*/ + + + /** + * Constructor. + * @param string $imap_url formated for imap_open() + */ + function imapPamDrivers($imap_url){ + $this->__construct($imap_url); + } + + + /** + * The constructor + * + * @param string $imap_url formated for imap_open() + */ + function __construct($imap_url) + { + global $c; + if (empty($imap_url)){ + $c->messages[] = sprintf(i18n('drivers_imap_pam : imap_url parameter not configured in /etc/davical/*-conf.php')); + $this->valid=false; + return ; + } + } +} + + +/** +* Check the username / password against the PAM system +*/ +function IMAP_PAM_check($username, $password ){ + global $c; + + /** + * @todo Think of the children! This is a horribly insecure use of unvalidated user input! Probably it should be done with a popen or something, and it seems remarkably dodgy to expect that naively quoted strings will work in any way reliably. + * Meanwhile, I've quickly hacked something basic in place to improve the situation. No quotes/backslashes in passwords for YOU! + */ + + $username_ori = $username; + $username = escapeshellcmd($username); + //$password = escapeshellcmd($password); + + //$imap_url = '{localhost:143/imap/notls}'; + //$imap_url = '{localhost:993/imap/ssl/novalidate-cert}'; + $imap_url = $c->authenticate_hook['config']['imap_url']; + $auth_result = "ERR"; + + $imap_stream = @imap_open($imap_url, $username, $password, OP_HALFOPEN); + //print_r(imap_errors()); + if ( $imap_stream ) { + // disconnect + imap_close($imap_stream); + // login ok + $auth_result = "OK"; + } + + if ( $auth_result == "OK") { + if ( $usr = getUserByName($username) ) { + return $usr; + } + else { + dbg_error_log( "PAM", "user %s doesn't exist in local DB, we need to create it",$username ); + $cmd = "getent passwd '$username'"; + $getent_res = exec($cmd); + $getent_arr = explode(":", $getent_res); + $fullname = $getent_arr[4]; + if(empty($fullname)) { + $fullname = $username; + } + $usr = (object) array( + 'user_no' => 0, + 'username' => $username, + 'active' => 't', + 'email' => $username . "@" . $c->authenticate_hook['config']['email_base'], + 'updated' => date(), + 'fullname' => $fullname + ); + + UpdateUserFromExternal( $usr ); + return $usr; + } + } + else { + dbg_error_log( "PAM", "User %s is not a valid username (or password was wrong)", $username ); + return false; + } + +}