From 2a086c3b01614502c1c293621716962ab2d7cb48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Rodier?= Date: Thu, 9 Oct 2014 16:01:41 +0100 Subject: [PATCH 1/2] Run a script everytime the impersonate facility is used Add a perl example script that can be used from dovecot post login script as well. Removed useless closing php tag Removed some trailing spaces ant tabs --- config.inc.php.dist | 5 ++- dovecot_impersonate.php | 44 +++++++++++++--------- notify-example/login-report.ini | 6 +++ notify-example/master-user-report.pl | 55 ++++++++++++++++++++++++++++ notify-example/post-login.sh | 12 ++++++ notify-example/readme.txt | 22 +++++++++++ 6 files changed, 126 insertions(+), 18 deletions(-) create mode 100644 notify-example/login-report.ini create mode 100755 notify-example/master-user-report.pl create mode 100755 notify-example/post-login.sh create mode 100644 notify-example/readme.txt diff --git a/config.inc.php.dist b/config.inc.php.dist index a631d36..aaeead5 100644 --- a/config.inc.php.dist +++ b/config.inc.php.dist @@ -7,4 +7,7 @@ $rcmail_config['dovecot_impersonate_seperator'] = '*'; -?> +// call a script everytime an account is impersonated +$rcmail_config['dovecot_impersonate_notify'] = + '/usr/local/bin/master-user-report.pl --remote-ip={{REMOTE_ADDR}} --server-ip={{SERVER_ADDR}} --master="{{MASTER}}" --account="{{ACCOUNT}}"'; + diff --git a/dovecot_impersonate.php b/dovecot_impersonate.php index 1523cf3..c9d1446 100644 --- a/dovecot_impersonate.php +++ b/dovecot_impersonate.php @@ -2,52 +2,62 @@ /** * This plugin lets you impersonate another user using a master login. Only works with dovecot. - * + * * http://wiki.dovecot.org/Authentication/MasterUsers - * + * * @author Cor Bosman (roundcube@wa.ter.net) */ - + class dovecot_impersonate extends rcube_plugin { - - public function init() - { + + public function init() + { $this->add_hook('storage_connect', array($this, 'impersonate')); $this->add_hook('managesieve_connect', array($this, 'impersonate')); - $this->add_hook('authenticate', array($this, 'login')); - $this->add_hook('sieverules_connect', array($this, 'impersonate_sieve')); + $this->add_hook('authenticate', array($this, 'login')); + $this->add_hook('sieverules_connect', array($this, 'impersonate_sieve')); } - + function login($data) { // find the seperator character $rcmail = rcmail::get_instance(); $this->load_config(); - + $seperator = $rcmail->config->get('dovecot_impersonate_seperator', '*'); - + if(strpos($data['user'], $seperator)) { $arr = explode($seperator, $data['user']); if(count($arr) == 2) { $data['user'] = $arr[0]; $_SESSION['plugin.dovecot_impersonate_master'] = $seperator . $arr[1]; + + // should we notify someone ? + $notify = $rcmail->config->get('dovecot_impersonate_notify'); + if ( !empty($notify) ) { + $notify = str_replace('{{REMOTE_ADDR}}', $_SERVER['REMOTE_ADDR'], $notify); + $notify = str_replace('{{SERVER_ADDR}}', $_SERVER['SERVER_ADDR'], $notify); + $notify = str_replace('{{ACCOUNT}}', $arr[0], $notify); + $notify = str_replace('{{MASTER}}', $arr[1], $notify); + system($notify); + } } + } return($data); } - + function impersonate($data) { if(isset($_SESSION['plugin.dovecot_impersonate_master'])) { - $data['user'] = $data['user'] . $_SESSION['plugin.dovecot_impersonate_master']; + $data['user'] = $data['user'] . $_SESSION['plugin.dovecot_impersonate_master']; } return($data); } - + function impersonate_sieve($data) { if(isset($_SESSION['plugin.dovecot_impersonate_master'])) { - $data['username'] = $data['username'] . $_SESSION['plugin.dovecot_impersonate_master']; + $data['username'] = $data['username'] . $_SESSION['plugin.dovecot_impersonate_master']; } return($data); } - + } -?> diff --git a/notify-example/login-report.ini b/notify-example/login-report.ini new file mode 100644 index 0000000..14b3c1d --- /dev/null +++ b/notify-example/login-report.ini @@ -0,0 +1,6 @@ +[Email] +Dest=administrator@example.com +From=postmaster@example.com +Server=smtp.example.com +Bcc=administrator2@example.com + diff --git a/notify-example/master-user-report.pl b/notify-example/master-user-report.pl new file mode 100755 index 0000000..2578989 --- /dev/null +++ b/notify-example/master-user-report.pl @@ -0,0 +1,55 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use Getopt::Long; +use Config::Tiny; +use MIME::Lite; + +# Get from command lineenvironmen +my $remoteAddress; +my $serverAddress; +my $account; +my $master; + +GetOptions( + 'remote-ip=s' => \$remoteAddress, + 'server-ip=s' => \$serverAddress, + 'master=s' => \$master, + 'account=s' => \$account); + +# Get variables from config files +my $Config = Config::Tiny->new; +$Config = Config::Tiny->read('/etc/dovecot/login-report.ini'); + +my $emailDest = $Config->{Email}->{Dest}; +my $emailFrom = $Config->{Email}->{From}; +my $emailCc = $Config->{Email}->{Cc} || ''; +my $emailBcc = $Config->{Email}->{Bcc} || ''; +my $smtpServer = $Config->{Email}->{Server} || 'localhost'; + +# be sure that the emails are correctly handled +$account =~ s/ /./g; +$master =~ s/ /./g; + +# Send a message to whom is concerned +my $emailSubject = 'Master login facility used'; +my $emailBody = "The master login facility has been used:\n\n"; +$emailBody .= "- Server address : $serverAddress\n"; +$emailBody .= "- Remote address : $remoteAddress\n"; +$emailBody .= "- Account accessed : $account\n"; +$emailBody .= "- Master account : $master\n"; +$emailBody .= "\n\n"; + +# print $emailBody; +my $msg = MIME::Lite->new( +From => $emailFrom, +To => $emailDest, +Cc => $emailCc, +Bcc => $emailBcc, +Subject => $emailSubject, +Data => $emailBody); +$msg->send('smtp', $smtpServer); + +# $msg->send('smtp', $smtpServer, AuthUser => $mailUser, AuthPass => $mailPassword); + diff --git a/notify-example/post-login.sh b/notify-example/post-login.sh new file mode 100755 index 0000000..aef2efe --- /dev/null +++ b/notify-example/post-login.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# Check if it is a master user login +if [ "$MASTER_USER" != "" ]; then + /usr/local/bin/master-user-report.pl --remote-ip=$IP --server-ip=$LOCAL_IP --master=$MASTER_USER --account="$USER" +fi + +# Assign the master user to allow him to read all mailboxes +export MASTER_USER="$USER" + +exec "$@" + diff --git a/notify-example/readme.txt b/notify-example/readme.txt new file mode 100644 index 0000000..a885631 --- /dev/null +++ b/notify-example/readme.txt @@ -0,0 +1,22 @@ +This folder contains a set of files you can use to notify people when the dovecot's impersonate facility has been used. + +- login-report.ini : to be placed in /etc/dovecot/, contains initialisation variable for emails, +- master-user-report.pl : a script to be placed in /usr/local/bin, for instance. +- post-login.sh : to be placed for instance in /etc/dovecot/scripts + + +In dovecot, you need to specify the post login script, if not done already: + +# The service name below doesn't actually matter. +service imap-postlogin { + # all post-login scripts are executed via script-login binary + executable = script-login /etc/dovecot/scripts/post-login.sh + + # the script process runs as the user specified here (v2.0.14+): + user = $default_internal_user + # this UNIX socket listener must use the same name as given to imap executable + unix_listener imap-postlogin { + } +} + + From 7b2820863cd33b67216e3bfabf484b16e3b549bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Rodier?= Date: Thu, 9 Oct 2014 16:09:24 +0100 Subject: [PATCH 2/2] Added a notification section in the README.md file --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 7758596..345cd72 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,10 @@ Password: password_of_master The plugin then strips the master info from the form, so all preferences are correctly fetched for the user. (else it would try to find preferences for user*master). If you use any other plugins that use the authenticate hook, you might want to make this plugin the first plugin. +CUSTOM NOTIFICATIONS +-------------------- + +You can also run a custom script everytime the impersonate is run, for instance to notify administrator accounts, or send alerts to another email address. See the notify-example folder. To avoid the script being called every time the user refresh the session - and keep the session opened, use imapproxy. OLD VERSIONS ------------