From 4b91e55275ce51cb5268b314cd25923007942ea3 Mon Sep 17 00:00:00 2001 From: ralf Date: Tue, 5 Jul 2022 15:16:01 +0200 Subject: [PATCH] * Mail/Dovecot: allow to use admin credentials to access mail when no session password is available, e.g. for SSO --- admin/inc/class.admin_mail.inc.php | 8 +++--- admin/templates/default/mailaccount.xet | 4 +++ api/src/Mail/Account.php | 34 +++++++++++++++++++++++-- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/admin/inc/class.admin_mail.inc.php b/admin/inc/class.admin_mail.inc.php index 6c16e59c2a..5762e8a76c 100644 --- a/admin/inc/class.admin_mail.inc.php +++ b/admin/inc/class.admin_mail.inc.php @@ -880,8 +880,8 @@ class admin_mail elseif ($content['acc_id'] > 0) { try { - $account = Mail\Account::read($content['acc_id'], $this->is_admin && $content['called_for'] ? - $content['called_for'] : $GLOBALS['egw_info']['user']['account_id']); + $account = Mail\Account::read($content['acc_id'], $this->is_admin && !empty($content['called_for']) ?: + $GLOBALS['egw_info']['user']['account_id']); $account->getUserData(); // quota, aliases, forwards etc. $content += $account->params; $content['acc_sieve_enabled'] = (string)($content['acc_sieve_enabled']); @@ -926,7 +926,7 @@ class admin_mail 'account_id' => true, 'button[multiple]' => true, 'acc_user_editable' => true, 'acc_further_identities' => true, 'acc_imap_type' => true, 'acc_imap_logintype' => true, 'acc_domain' => true, - 'acc_imap_admin_username' => true, 'acc_imap_admin_password' => true, + 'acc_imap_admin_username' => true, 'acc_imap_admin_password' => true, 'acc_imap_admin_use_without_pw' => true, 'acc_smtp_type' => true, 'acc_smtp_auth_session' => true, ); } @@ -1644,4 +1644,4 @@ class admin_mail_logger { fwrite($this->fp, $msg."\n"); } -} +} \ No newline at end of file diff --git a/admin/templates/default/mailaccount.xet b/admin/templates/default/mailaccount.xet index 0aac424c4e..ffaf38c91c 100644 --- a/admin/templates/default/mailaccount.xet +++ b/admin/templates/default/mailaccount.xet @@ -100,6 +100,10 @@ + + + + diff --git a/api/src/Mail/Account.php b/api/src/Mail/Account.php index 307afb65c9..e8d2d6c02c 100644 --- a/api/src/Mail/Account.php +++ b/api/src/Mail/Account.php @@ -89,6 +89,7 @@ use Horde_Mail_Transport_Smtphorde; * @property-read int $acc_imap_default_quota quota in MB, if no user specific one set * @property-read int $acc_imap_timeout timeout for imap connection, default 20s * @property-read array $notif_folders folders user wants to be notified about new mails + * @property-read bool $acc_admin_use_without_pw use admin credentials for users personal mail account, if user password is not in session eg. SSO * * You can overwrite values in all mail accounts by creating a file /var/www/mail-overwrites.inc.php, see method getParamOverwrites. */ @@ -257,6 +258,12 @@ class Account implements \ArrayAccess // read credentials from database $params += Credentials::read($params['acc_id'], null, $called_for ? array(0, $called_for) : $called_for, $this->on_login); + if (isset($params['acc_imap_admin_username']) && $params['acc_imap_admin_username'][0] === '*') + { + $params['acc_admin_use_without_pw'] = true; + $params['acc_imap_admin_username'] = substr($params['acc_imap_admin_username'], 1); + } + if (!isset($params['notify_folders'])) { $params += Notifications::read($params['acc_id'], $called_for ? array(0, $called_for) : $called_for); @@ -269,6 +276,13 @@ class Account implements \ArrayAccess $params = Credentials::from_session( (!isset($called_for) ? array() : array('acc_smtp_auth_session' => false)) + $params, !isset($called_for) ) + $params; + + // check if we should use admin-credentials, if no session password exists, eg. SSO without password + if (!empty($params['acc_admin_use_without_pw']) && empty($params['acc_imap_password'])) + { + $params['acc_imap_username'] .= '*'.$params['acc_imap_admin_username']; + $params['acc_imap_password'] = $params['acc_imap_admin_password']; + } } } $this->params = $params; @@ -374,6 +388,18 @@ class Account implements \ArrayAccess * // other imap-server to overwrite ... * ]; * + * // or you can provide a function, which gets passed all acc_* parameters and can modify them: + * function _mail_overwrites(array $params) + * { + * switch($params['acc_imap_host']) + * { + * case 'mail': + * $params['acc_imap_host'] = 'other host or IP'; + * break; + * } + * return $params; + * } + * * @return array */ function getParamOverwrites() @@ -385,7 +411,7 @@ class Account implements \ArrayAccess { include($f); } - else + if (!isset($overwrites)) { $overwrites = []; } @@ -394,6 +420,10 @@ class Account implements \ArrayAccess { return array_merge($this->params, $overwrites[$this->acc_imap_host]); } + elseif (function_exists('_mail_overwrites')) + { + return _mail_overwrites($this->params); + } return $this->params; } @@ -1304,7 +1334,7 @@ class Account implements \ArrayAccess // store or delete admin credentials if ($data['acc_imap_admin_username'] && $data['acc_imap_admin_password']) { - Credentials::write($data['acc_id'], $data['acc_imap_admin_username'], + Credentials::write($data['acc_id'], (!empty($data['acc_admin_use_without_pw'])?'*':'').$data['acc_imap_admin_username'], $data['acc_imap_admin_password'], Credentials::ADMIN, 0, $data['acc_imap_admin_cred_id']); }