* Mail/Dovecot: allow to use admin credentials to access mail when no session password is available, e.g. for SSO

This commit is contained in:
ralf 2022-07-05 15:16:01 +02:00
parent a5fbb5c4ef
commit 94e74f8db4
3 changed files with 40 additions and 6 deletions

View File

@ -880,8 +880,8 @@ class admin_mail
elseif ($content['acc_id'] > 0) elseif ($content['acc_id'] > 0)
{ {
try { try {
$account = Mail\Account::read($content['acc_id'], $this->is_admin && $content['called_for'] ? $account = Mail\Account::read($content['acc_id'], $this->is_admin && !empty($content['called_for']) ?:
$content['called_for'] : $GLOBALS['egw_info']['user']['account_id']); $GLOBALS['egw_info']['user']['account_id']);
$account->getUserData(); // quota, aliases, forwards etc. $account->getUserData(); // quota, aliases, forwards etc.
$content += $account->params; $content += $account->params;
$content['acc_sieve_enabled'] = (string)($content['acc_sieve_enabled']); $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, 'account_id' => true, 'button[multiple]' => true, 'acc_user_editable' => true,
'acc_further_identities' => true, 'acc_further_identities' => true,
'acc_imap_type' => true, 'acc_imap_logintype' => true, 'acc_domain' => 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, 'acc_smtp_type' => true, 'acc_smtp_auth_session' => true,
); );
} }

View File

@ -100,6 +100,10 @@
<description for="acc_imap_admin_password" value="Password"/> <description for="acc_imap_admin_password" value="Password"/>
<passwd id="acc_imap_admin_password" size="32" maxlength="128" autocomplete="off"/> <passwd id="acc_imap_admin_password" size="32" maxlength="128" autocomplete="off"/>
</row> </row>
<row>
<description/>
<checkbox id="acc_admin_use_without_pw" label="Use admin credentials to connect without a session-password, e.g. for SSO"/>
</row>
<row disabled="!@admin_actions"> <row disabled="!@admin_actions">
<description value="Administration"/> <description value="Administration"/>
<toolbar id="admin_actions" default_execute="app.admin.account_edit_action"/> <toolbar id="admin_actions" default_execute="app.admin.account_edit_action"/>

View File

@ -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_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 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 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. * 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 // read credentials from database
$params += Credentials::read($params['acc_id'], null, $called_for ? array(0, $called_for) : $called_for, $this->on_login); $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'])) if (!isset($params['notify_folders']))
{ {
$params += Notifications::read($params['acc_id'], $called_for ? array(0, $called_for) : $called_for); $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( $params = Credentials::from_session(
(!isset($called_for) ? array() : array('acc_smtp_auth_session' => false)) + $params, !isset($called_for) (!isset($called_for) ? array() : array('acc_smtp_auth_session' => false)) + $params, !isset($called_for)
) + $params; ) + $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; $this->params = $params;
@ -374,6 +388,18 @@ class Account implements \ArrayAccess
* // other imap-server to overwrite ... * // 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 * @return array
*/ */
function getParamOverwrites() function getParamOverwrites()
@ -385,7 +411,7 @@ class Account implements \ArrayAccess
{ {
include($f); include($f);
} }
else if (!isset($overwrites))
{ {
$overwrites = []; $overwrites = [];
} }
@ -394,6 +420,10 @@ class Account implements \ArrayAccess
{ {
return array_merge($this->params, $overwrites[$this->acc_imap_host]); return array_merge($this->params, $overwrites[$this->acc_imap_host]);
} }
elseif (function_exists('_mail_overwrites'))
{
return _mail_overwrites($this->params);
}
return $this->params; return $this->params;
} }
@ -1303,7 +1333,7 @@ class Account implements \ArrayAccess
// store or delete admin credentials // store or delete admin credentials
if ($data['acc_imap_admin_username'] && $data['acc_imap_admin_password']) 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_password'], Credentials::ADMIN, 0,
$data['acc_imap_admin_cred_id']); $data['acc_imap_admin_cred_id']);
} }