Compare commits

...

No commits in common. 'master' and 'gh-pages' have entirely different histories.

@ -1,34 +0,0 @@
name: GitHubBuild
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Validate composer.json and composer.lock
run: composer validate
- name: setup templates_c
run: mkdir templates_c || true
- name: touch config.local.php
run: touch config.local.php && php -v
- name: Install dependencies
run: composer install --prefer-dist --no-progress --no-suggest
- name: Build/test
run: composer build
- name: setup coveralls
run: mkdir -p build/logs || true
- name: Coveralls
run: vendor/bin/coveralls ./clover.xml || true
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}

7
.gitignore vendored

@ -1,7 +0,0 @@
/config.local.php
/templates_c/*.tpl.php
/templates_c/*menu.conf.php
/vendor/
/.php_cs.cache
/.idea
/composer.lock

@ -1,23 +0,0 @@
<?php
$finder = PhpCsFixer\Finder::create()
->exclude('lib')
->exclude('vendor')
->exclude('templates')
->exclude('templates_c')
->exclude('debian')
->files()->notName('config.inc.php')->notName('config.local.php')
->in(__DIR__);
return PhpCsFixer\Config::create()
->setFinder($finder)
->setRules(array(
'@PSR2' => true,
'braces' => array(
'position_after_functions_and_oop_constructs' => 'same',
),
'method_argument_space' => false, # don't break formatting in initStruct()
'no_spaces_inside_parenthesis' => false, # don't break formatting in initStruct()
));
/* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4 ft=php: */

@ -1,32 +0,0 @@
language: php
php:
- 7.2
- 7.3
- 7.4
services:
- mysql
- postgresql
cache:
directories:
- $HOME/.composer/cache
- $HOME/vendor
before_install:
- mysql -e 'CREATE DATABASE postfixadmin;'
- psql -c 'create database postfixadmin;' -U postgres
before_script:
- travis_retry composer install --no-interaction --prefer-source --dev
- mkdir -p build/logs
script:
- composer build
- DATABASE=sqlite vendor/bin/phpunit tests/
- DATABASE=mysql vendor/bin/phpunit --coverage-clover=build/logs/clover.xml tests/
- DATABASE=postgresql vendor/bin/phpunit tests/
after_success:
- travis_retry php vendor/bin/php-coveralls

@ -1,52 +0,0 @@
#
# Postfix Admin ADDITIONS
#
BEFORE YOU START
----------------
**** ALL THESE SCRIPTS ARE CREATED BY THIRD PARTIES ****
**** THEY ARE AS IS, USE AT YOUR OWN RISK! ****
ADDITIONS
---------
In this directory you will find additional scripts that are build by others.
- change_password.tgz
by George Vieira <george at citadelcomputer dot com dot au>
SquirrelMail plugin to change your passwor
- cleanupdirs.pl
by jared bell <jared at beol dot net>
Displays a list of mailboxes that need to be deleted
- mailbox_remover.pl
by Petr Znojemsky
Deletes all unused mailboxes
- mkeveryone.pl
by Joshua Preston
Generate an 'everybody' alias for a domain.
- pfa_maildir_cleanup.pl
by Stephen Fulton <sfulton at esoteric dot ca>
Deletes all unused mailboxes
- postfixadmin-0.3-1.4.tar.gz
by Florian Kimmerl <info at spacekoeln dot de>
The Postfixadmin SquirrelMail plugin let users change their virtual alias,
vacation status/message and password.
- virtualmaildel.php
by George Vieira <george at citadelcomputer dot com dot au>
Deletes all unused mailboxes
- postfixadmin-mailbox-postcreation.sh
- postfixadmin-mailbox-postdeletion.sh
- postfixadmin-domain-postdeletion.sh
by Troels Arvin <troels@arvin.dk>
Examples of scripts relevant to the optional
$CONF['mailbox_postcreation_script'],
$CONF['mailbox_postdeletion_script'] and
$CONF['domain_postdeletion_script'] configuration options.

Binary file not shown.

@ -1,112 +0,0 @@
#!/usr/bin/perl -w
################################################################################
#
# cleanupdirs 1.2 by jared bell <jared@beol.net>
#
# display/remove maildir & domains directory tree's not listed in the postfix
# mysql database. currently setup for use with postfixadmin, but can be
# adapted. edit settings where it says 'change settings as needed.' by default
# this program will display a list of directories which need deleted, nothing
# is actually deleted. to change this behavior, look into the command line
# arguments.
#
# command line arguments:
# --delete
# force automatic deletion of directories. instead of displaying a list
# of deleted directories, they will be logged in the specified logfile.
# --print
# display deleted directories as well as log them. only valid when
# '--delete' has been specified.
#
# settings:
# $root_path = "/home/vmail";
# if maildir is '/home/vmail/domain.tld/user' then '/home/vmail' is the
# $root_path. if your maildirs are '/home/vmail/user@domain.tld' then
# this program will need to be modified in order to work right.
# $logfile = "/var/log/removed_maildirs.log";
# the logfile to use when $delete_old_dirs is set to 1
# $db_* = "*";
# sets the host, port, database, user and pass to your mysql server
#
# version history:
# 1.2 - removed uneeded settings. added '--print' command line argument
# 1.1 - added '--delete' command line argument
# 1.0 - initial release
#
################################################################################
use strict;
use DBI;
use File::Path;
use Getopt::Long;
### change settings as needed, see notes above #################################
our $root_path = "/home/vmail";
our $logfile = "/var/log/removed_maildirs.log";
our $db_hostname = "localhost";
our $db_port = "3306"; # this script currently supports MySQL only
our $db_database = "postfix";
our $db_username = "someuser";
our $db_password = "somepass";
# instead of changing this script, you can put your settings to /etc/mail/postfixadmin/cleanupdirs.conf
# just use perl syntax there to fill the variables listed above (without the "our" keyword). Example:
# $db_username = 'mail';
if (-f "/etc/mail/postfixadmin/cleanupdirs.conf") {
require "/etc/mail/postfixadmin/cleanupdirs.conf";
}
################################################################################
### begin program ##############################################################
my(@dirs_to_delete, $logfile_open);
my $delete_old_dirs = 0; # do not delete by default, use cmdline to change this
my $print_also = 0; # also print items when deleting, use cmdline to change this
GetOptions ('delete' => \$delete_old_dirs, 'print' => \$print_also);
my $conn_info = "DBI:mysql:database=$db_database;hostname=$db_hostname;port=$db_port";
my $dbh = DBI->connect($conn_info, $db_username, $db_password)
or die $DBI::errstr;
opendir DOMAINDIR, $root_path
or die "Unable to access directory '$root_path' ($!)";
foreach my $domain_dir (sort readdir DOMAINDIR) {
next if $domain_dir =~ /^\./; # skip dotted dirs
next if (! -d "$root_path/$domain_dir"); # skip everything that is not a directory
my $full_domain_dir = "$root_path/$domain_dir";
opendir USERDIR, $full_domain_dir
or die "Unable to access directory '$full_domain_dir' ($!)";
foreach my $user_dir (sort readdir USERDIR) {
next if $user_dir =~ /^\./; # skip dotted dirs
push @dirs_to_delete, "$full_domain_dir/$user_dir"
if &check_dir("SELECT maildir FROM mailbox WHERE maildir = ?",
"$domain_dir/$user_dir/"); # end slash needed for checkdir
}
push @dirs_to_delete, $full_domain_dir
if &check_dir("SELECT domain FROM domain WHERE domain = ?", $domain_dir);
}
closedir USERDIR;
closedir DOMAINDIR;
$dbh->disconnect;
if (@dirs_to_delete) {
foreach my $to_delete (@dirs_to_delete) {
if ($delete_old_dirs == 1) {
$logfile_open = open LOGFILE, ">> $logfile"
or die "Unable to append logfile '$logfile' ($!)"
unless $logfile_open;
rmtree $to_delete;
print LOGFILE localtime() . " Deleting directory '$to_delete'\n";
print localtime() . " Deleting directory '$to_delete'\n"
if $print_also;
} else {
print localtime() . " Need to delete directory '$to_delete'\n";
}
}
}
close LOGFILE if $logfile_open;
sub check_dir {
my($query, $dir) = @_;
my $sth = $dbh->prepare($query);
my $num_rows = $sth->execute($dir);
$sth->finish;
($num_rows eq "0E0") ? 1 : 0;
}

@ -1,40 +0,0 @@
#!/usr/bin/perl -w
#
# Postfix Admin
#
# LICENSE
# This source file is subject to the GPL license that is bundled with
# this package in the file LICENSE.TXT.
#
# Further details on the project are available at http://postfixadmin.sf.net
#
# @version $Id$
# @license GNU GPL v2 or later.
#
#
# Really crude attempt at taking all users from a local
# passwd file (/etc/shadow) and creating postfixadmin mailboxes for them.
#
# The script outputs some SQL, which you need to then insert into your database
# as appropriate.
#
# Notes:
# 1) Change $mydomain and $true as required.
# 2) Ideally it should parse /etc/passwd, or call the getpw()? function and
# populate someone's name if known.
# 3) There's plenty of room for improvement.
#
# Original author: David Goodwin <david at palepurple-co-uk> - 2007/10/05.
#
use strict;
open(FH, '</etc/shadow') or die ('Cannot open shadow file; you need to be root - ' . $!);
my $mydomain = "test.com";
my $true = "t"; # t for pgsql; 1 for mysql
foreach(<FH>) {
my ($username, $password) = split(':', $_);
next if $password eq '!';
next if $password eq '*';
my $maildir = "$username\@$mydomain/";
print "insert into mailbox (username, password, domain, active, maildir) values ('$username', '$password', '$mydomain', $true, '$maildir');\n";
}

@ -1,8 +0,0 @@
Version 0.1 -- 26/10/2009
---------------------------
* Public Release.
* Postcreation, Postdeletion and Postedit hooks.

@ -1,7 +0,0 @@
Configuración
-------------
- Edita el fichero cyrus.conf y modifica las variables $cyrus_*. El usuario debe tener permisos sobre todas las cuentas.
- Edita los ficheros cyrus-*.pl y cambia la ruta de cyrus.conf (linea require '/path/to/cyrus.conf';)

@ -1,7 +0,0 @@
Configuration
-------------
- Edit cyrus.conf and set $cyrus_* variables correctly. User must have permission over all accounts.
- Edit cyrus-*.pl and change path to cyrus.conf (require '/path/to/cyrus.conf'; line)

@ -1,36 +0,0 @@
#!/usr/bin/perl
# Cyrus Mailbox creation
#
# Iñaki Rodriguez (irodriguez@virtualminds.es / irodriguez@ackstorm.es)
#
# LICENSE
# This source file is subject to the GPL license that is bundled with
# this package in the file LICENSE.TXT.
#
# (26/10/2009)
use Cyrus::IMAP::Admin;
require '/etc/mail/postfixadmin/cyrus.conf';
use strict;
use vars qw($cyrus_user $cyrus_password $cyrus_host);
my %opts;
my $mailbox = mailbox_name($ARGV[0]);
my $client = Cyrus::IMAP::Admin->new($cyrus_host);
die_on_error($client);
$opts{-user} = $cyrus_user;
$opts{-password} = $cyrus_password;
$client->authenticate(%opts);
die_on_error($client);
$client->create($mailbox);
die_on_error($client);
$client->setquota($mailbox,'STORAGE',scalar $ARGV[3]) if ($ARGV[3] > 0);
die_on_error($client);

@ -1,36 +0,0 @@
#!/usr/bin/perl
# Cyrus Mailbox deletion
#
# Iñaki Rodriguez (irodriguez@virtualminds.es / irodriguez@ackstorm.es)
#
# LICENSE
# This source file is subject to the GPL license that is bundled with
# this package in the file LICENSE.TXT.
#
# (26/10/2009)
use Cyrus::IMAP::Admin;
require '/etc/mail/postfixadmin/cyrus.conf';
use strict;
use vars qw($cyrus_user $cyrus_password $cyrus_host);
my %opts;
my $mailbox = mailbox_name($ARGV[0]);
my $client = Cyrus::IMAP::Admin->new($cyrus_host);
die_on_error($client);
$opts{-user} = $cyrus_user;
$opts{-password} = $cyrus_password;
$client->authenticate(%opts);
die_on_error($client);
$client->setacl($mailbox,$cyrus_user => 'all');
die_on_error($client);
$client->deletemailbox($mailbox);
die_on_error($client);

@ -1,33 +0,0 @@
#!/usr/bin/perl
# Cyrus Mailbox edition
#
# Iñaki Rodriguez (irodriguez@virtualminds.es / irodriguez@ackstorm.es)
#
# LICENSE
# This source file is subject to the GPL license that is bundled with
# this package in the file LICENSE.TXT.
#
# (26/10/2009)
use Cyrus::IMAP::Admin;
require '/etc/mail/postfixadmin/cyrus.conf';
use strict;
use vars qw($cyrus_user $cyrus_password $cyrus_host);
my %opts;
my $mailbox = mailbox_name($ARGV[0]);
my $client = Cyrus::IMAP::Admin->new($cyrus_host);
die_on_error($client);
$opts{-user} = $cyrus_user;
$opts{-password} = $cyrus_password;
$client->authenticate(%opts);
die_on_error($client);
$client->setquota($mailbox,'STORAGE',scalar $ARGV[3]) if ($ARGV[3] > 0);
die_on_error($client);

@ -1,31 +0,0 @@
#!/usr/bin/perl
# Config
$cyrus_user = 'cyrus';
$cyrus_password = 'cyruspass';
$cyrus_host = 'localhost';
# unixhierarchysep => 1 (yes) / 0 (no)
$unixhierarchysep = 1;
# Common routines
sub mailbox_name {
my $mailbox = shift;
if($unixhierarchysep) {
$mailbox = 'user/'.$ARGV[0];
} else {
$mailbox = 'user.'.$ARGV[0];
}
return $mailbox;
}
sub die_on_error {
my $cyradm = shift;
if($cyradm->error) { die $cyradm->error; }
}
1;

@ -1,77 +0,0 @@
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
$ENV{'PATH'} = "/sbin:/bin:/usr/sbin:/usr/bin";
my ($domain);
my $list = 0;
(help()) if (!$ARGV[0]);
GetOptions ('l' => \$list, 'd=s' => \$domain) or (help());
(list_queue()) if ($list == 1);
(delete_queue()) if ($domain);
sub delete_queue {
my $ids = `postqueue -p`;
my @ids = split /\n/, $ids;
for my $id (@ids) {
next if $id =~ /^[\s\(-]/;
chomp $id;
next unless $id;
$id =~ s/(.*?)\**\s.*/$1/;
#print "$id\n";
my $match = `postcat -q $id | grep '$domain'`;
next unless $match;
#print "Deleting ID: $id\n";
my $saida = `postsuper -d $id`;
print $saida;
}
}
sub list_queue {
my %hash_mail = ();
my @queue = `postqueue -p`;
my($queue,$key,$total);
foreach $queue(@queue) {
chomp $queue;
if ( $queue =~ /^\s+.*\@(.*)/ ) {
$hash_mail{$1}++;
}
}
print"\nTOTAL\tTO\n";
print"-----
----------------------------------------------------------------\n";
foreach $key (reverse sort { $hash_mail{$a} <=> $hash_mail{$b}} keys
%hash_mail) {
$total += $hash_mail{$key};
print"$hash_mail{$key} - $key\n";
}
print"\n$total -> TOTAL QUEUE\n";
}
sub help {
print "Usage $0 -l To list a row of E-mail
Usage $0 -d domain.com To delete the mensgens the Domain\n";
}

@ -1,160 +0,0 @@
#!/usr/bin/perl
use DBI;
use MIME::Base64;
# use Data::Dumper;
use File::Temp qw/ mkstemp /;
use Sys::Syslog;
# require liblockfile-simple-perl
use LockFile::Simple qw(lock trylock unlock);
######################################################################
########## Change the following variables to fit your needs ##########
# database settings
# database backend - uncomment one of these
our $db_type = 'Pg';
#my $db_type = 'mysql';
# host name
our $db_host="127.0.0.1";
# database name
our $db_name="postfix";
# database username
our $db_username="mail";
# database password
our $db_password="CHANGE_ME!";
# Where to create a lockfile; please ensure path exists.
our $run_dir="/var/lock/fetchmail";
# in case you want to use dovecot deliver to put the mail directly into the users mailbox,
# set "mda" in the fetchmail table to the keyword "dovecot".
# Where the delivery binary is located
$dovecot_deliver = "/usr/lib/dovecot/deliver";
# instead of changing this script, you can put your settings to /etc/mail/postfixadmin/fetchmail.conf
# just use perl syntax there to fill the variables listed above (without the "our" keyword). Example:
# $db_username = 'mail';
if (-f "/etc/mail/postfixadmin/fetchmail.conf") {
require "/etc/mail/postfixadmin/fetchmail.conf";
}
#################### Don't change anything below! ####################
######################################################################
openlog("fetchmail-all", "pid", "mail");
sub log_and_die {
my($message) = @_;
syslog("err", $message);
die $message;
}
# read options and arguments
$configfile = "/etc/fetchmail-all/config";
@ARGS1 = @ARGV;
while ($_ = shift @ARGS1) {
if (/^-/) {
if (/^--config$/) {
$configfile = shift @ARGS1
}
}
}
# use specified config file
if (-e $configfile) {
do $configfile;
}
if($db_type eq "Pg" || $db_type eq "mysql") {
$dsn = "DBI:$db_type:database=$db_name;host=$db_host";
} else {
log_and_die "unsupported db_type $db_type";
}
if(!-d $run_dir) {
log_and_die("Please create: $run_dir");
}
$lock_file=$run_dir . "/fetchmail-all.lock";
$lockmgr = LockFile::Simple->make(-autoclean => 1, -max => 1);
$lockmgr->lock($lock_file) || log_and_die "can't lock ${lock_file}";
# database connect
$dbh = DBI->connect($dsn, $db_username, $db_password) || log_and_die "cannot connect the database";
if($db_type eq "Pg") {
$sql_cond = "active = 't' AND date_part('epoch',now())-date_part('epoch',date)";
} elsif($db_type eq "mysql") {
$sql_cond = "active = 1 AND unix_timestamp(now())-unix_timestamp(date)";
}
$sql = "
SELECT id,mailbox,src_server,src_auth,src_user,src_password,src_folder,fetchall,keep,protocol,mda,extra_options,usessl, sslcertck, sslcertpath, sslfingerprint
FROM fetchmail
WHERE $sql_cond > poll_time*60
";
my (%config);
map{
my ($id,$mailbox,$src_server,$src_auth,$src_user,$src_password,$src_folder,$fetchall,$keep,$protocol,$mda,$extra_options,$usessl,$sslcertck,$sslcertpath,$sslfingerprint)=@$_;
syslog("info","fetch ${src_user}@${src_server} for ${mailbox}");
$cmd="user '${src_user}' there with password '".decode_base64($src_password)."'";
$cmd.=" folder '${src_folder}'" if ($src_folder);
if ($mda) {
if ($mda eq "dovecot") {
$cmd.=" mda \"${dovecot_deliver} -d ${mailbox}\" ";
} else {
$cmd.=" mda ".$mda
}
}
# $cmd.=" mda \"/usr/local/libexec/dovecot/deliver -m ${mailbox}\"";
$cmd.=" is '${mailbox}' here";
$cmd.=" keep" if ($keep);
$cmd.=" fetchall" if ($fetchall);
$cmd.=" ssl" if ($usessl);
$cmd.=" sslcertck" if($sslcertck);
$cmd.=" sslcertpath $sslcertpath" if ($sslcertck && $sslcertpath);
$cmd.=" sslfingerprint \"$sslfingerprint\"" if ($sslfingerprint);
$cmd.=" ".$extra_options if ($extra_options);
$text=<<TXT;
set postmaster "postmaster"
set nobouncemail
set no spambounce
set properties ""
set syslog
TXT
$text.="poll ${src_server} with proto ${protocol}";
$text.=" service ${src_port}" if ($src_port);
$text.="\n $cmd";
($file_handler, $filename) = mkstemp( "/tmp/fetchmail-all-XXXXX" ) or log_and_die "cannot open/create fetchmail temp file";
print $file_handler $text;
close $file_handler;
$ret=`/usr/bin/fetchmail -f $filename -i $run_dir/fetchmail.pid`;
unlink $filename;
$sql="UPDATE fetchmail SET returned_text=".$dbh->quote($ret).", date=now() WHERE id=".$id;
$dbh->do($sql);
}@{$dbh->selectall_arrayref($sql)};
$lockmgr->unlock($lock_file);
closelog();

@ -1,231 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Script takes a CSV list of users and does a 'bulk' insertion into mysql.
#
# Copyright (C) 2009 Simone Piccardi
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
import csv
import getopt
import sys
import re
import time
import random, string
from datetime import datetime
from crypt import crypt
try:
import MySQLdb
except ImportError ,e:
print 'Cannot import the needed MySQLdb module, you must install it'
print 'on Debian systems just use the command'
print ' apt-get install python-mysqldb'
def usage():
print "Usage: inspostadmusers.py [options] users.csv"
print " -h print this help"
print " -t test run, do not insert, just print"
print " -u DB user"
print " -p DB password"
print " -D DB name"
print " -H DB host"
print " -q Quota in Mb (0 => no limit)"
print " -n char in seed"
print " -d debug info on"
print " -A create default alias for each domain"
print
print "the users.csv file must contains the user list with a line"
print "for each user, first line should be a title line with at least"
print "the following column names: "
print " * user - user part of the email (like user in user@domain.com)"
print " * password - cleartext password"
print " * domain - domain name (like 'domain.com')"
print " * name - full user name ('Name Surname')"
print
print "the 'name' column is optional, other columns will be ignored"
print
print "Known restrictions:"
print "* this script only works with MySQL"
print "* mailbox paths are hardcoded to domain/username/"
# option parsing
try:
opts, args = getopt.getopt(sys.argv[1:], 'u:p:d:D:H:htdA')
optval={}
for opt, val in opts:
if opt == "-h":
usage()
sys.exit(0)
else:
optval[opt]=val
except getopt.GetoptError:
usage()
sys.exit(2)
#
# Setup DB connection
#
MYSQLDB="postfixadmin"
MYSQLUSER="postfixadmin"
MYSQLPASSWORD=""
MYSQLHOST="localhost"
# settings by command line options
if optval.has_key('-u'):
MYSQLUSER = optval['-u']
if optval.has_key('-p'):
MYSQLPASSWORD = optval['-p']
if optval.has_key('-D'):
MYSQLDB = optval['-D']
if optval.has_key('-H'):
MYSQLHOST = optval['-H']
if optval.has_key('-q'):
quota = optval['-q']
else:
quota = 0
if optval.has_key('-n'):
seed_len = optval['-n']
else:
seed_len = 8
# check arguments, only the user list file must be present
if len(args) !=1:
print 'Need just one argument'
usage()
sys.exit(1)
# MySQL connection (skipped in test run)
if optval.has_key('-t'):
print "Test Run"
else:
try:
connection = MySQLdb.connect(host=MYSQLHOST, user=MYSQLUSER,
db=MYSQLDB, passwd=MYSQLPASSWORD)
except MySQLdb.MySQLError, e:
print "Database connection error"
print e
sys.exit(1)
cursor = connection.cursor()
#
# Main body
#
NOW = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# read and convert CSV data
lista = csv.DictReader(open(args[0]))
def gen_seed(seed_len, chars):
return '$1$'+''.join([random.choice(chars) for _ in xrange(seed_len)])+'$'
def insert_record(cursor,table,record):
columns = record.keys()
query = "INSERT INTO " + table + "(" + ','.join(columns) + ") VALUES (" + ','.join(len(columns)*['%s']) + ")"
try:
cursor.execute(query, record.values())
return 0
except MySQLdb.MySQLError, e:
print "Database insertion error"
print e
print "Record was:"
print record.values()
print "Query was:"
print query
# defining default values for tables (mailbox, alias and domain)
mailbox = {
'created': NOW,
'modified': NOW,
'active': 1,
'quota': quota
}
aliases = {
'created': NOW,
'modified': NOW,
'active': 1
}
domain = {
'description': "",
'aliases': 0,
'mailboxes': 0,
'quota': 0,
'transport': 'virtual',
'backupmx': 0,
'created': NOW,
'modified': NOW,
'active': 1
}
# list of default alias
def_alias = ['abuse','hostmaster','postmaster','webmaster']
domain_list = {}
chars = string.letters + string.digits
# loop over the CSV
for row in lista:
# create domain if it does not exists
if domain_list.has_key(row["domain"]):
if optval.has_key('-d'):
print "Domain " + row["domain"] + "already exixts"
else:
domain_list[row["domain"]] = 1
domain['domain'] = row["domain"]
if optval.has_key('-t'):
print "Inserting domain"
print domain
else:
insert_record(cursor,'domain',domain)
if optval.has_key('-A'):
for i in def_alias:
aliases['address']= i+'@'+row["domain"]
aliases['goto']= aliases['address']
aliases['domain'] = row["domain"]
if optval.has_key('-t'):
print "Inserting alias"
print aliases
else:
insert_record(cursor,'alias',aliases)
# build query data for mailbox table
mailbox['username']=row["user"]+'@'+row["domain"]
encpass=crypt(row["password"], gen_seed(seed_len,chars))
mailbox['password'] = encpass
mailbox['name'] = row["name"]
mailbox['maildir'] = row["domain"]+'/'+row["user"]+'/'
mailbox['local_part'] =row["user"]
mailbox['domain'] = row["domain"]
# build query data for alias table
aliases['address']= mailbox['username']
aliases['goto']= mailbox['username']
aliases['domain'] = row["domain"]
# inserting data for mailbox (and relate alias)
if optval.has_key('-t'):
print "Inserting mailbox"
print mailbox
print aliases
else:
insert_record(cursor,'mailbox',mailbox)
insert_record(cursor,'alias',aliases)
sys.exit(0)

@ -1,124 +0,0 @@
#!/usr/bin/perl
#
# by Petr Znojemsky (c) 2004
# Mailbox remover 0.1a 23/10/2004 - the very first version for MySQL
# removes maildirs from disk when they are not found in a database
#
# Added subdir support and pause --- Alan Batie 2007
# Lists directories to be deleted then pauses for 5 seconds for chance to abort
# $Id$
#
# All your maildirs or other directories could be accidentally removed.
# Use it at own risk. No warranties!
use strict;
use DBI;
use File::Path;
##########
# Set these variables according to your configuration
# when mailboxes are removed, save their tarballs here
my $archdir="/var/archive/mailboxes";
# expected to support z option, tweak invocation if you want different
my $archcmd="/usr/bin/tar";
# trailing slash not needed
my $maildir_path="/var/mail";
# find out if we need to check subdirs for mailboxes or just maildir_path
# $CONF['domain_path'] = 'YES';
my $pfadmin_config="/usr/local/www/postfixadmin/config.inc.php";
# database information
my $host="localhost";
my $port="3306";
my $userid="dbuser";
my $passwd="dbpw";
my $db="dbname";
############
my $connectionInfo="DBI:mysql:database=$db;$host:$port";
# make connection to database
my $dbh = DBI->connect($connectionInfo,$userid,$passwd);
# prepare and execute query
my $query = "SELECT maildir FROM mailbox";
my $sth = $dbh->prepare($query);
$sth->execute();
# assign fields to variables
my ($db_maildir, %db_maildirs);
$sth->bind_columns(\$db_maildir);
# load up directory list
while($sth->fetch()) {
$db_maildirs{$db_maildir} = 1;
}
$sth->finish();
# disconnect from database
$dbh->disconnect;
#
# find out if we need to check subdirs for mailboxes or just maildir_path
# $CONF['domain_path'] = 'YES';
#
my $use_subdirs = 0;
open(CONFIG, "<$pfadmin_config") || die "Can't open '$pfadmin_config': $!\n";
while(<CONFIG>) {
if (/\$CONF\['domain_path'\] *= *'([^']*)'/) {
$use_subdirs = ($1 =~ /yes/i);
}
}
close(CONFIG);
# store maildir list to %directories
# key is path, value is username to use in archive file
my %directories;
opendir(DIR, $maildir_path) || die "Cannot open dir $maildir_path: $!\n";
foreach my $name (readdir(DIR)) {
next if ($name eq '.' || $name eq '..' || ! -d "$maildir_path/$name");
if ($use_subdirs) {
opendir(SUBDIR, "$maildir_path/$name") || die "Cannot open dir $maildir_path/$name: $!\n";
foreach my $subname (readdir(SUBDIR)) {
next if ($subname eq '.' || $subname eq '..' || ! -d "$maildir_path/$name/$subname");
# db entry has trailing slash...
if (!defined($db_maildirs{"$name/$subname/"})) {
print "marking $maildir_path/$name/$subname for deletion.\n";
$directories{"$name/$subname"} = "$name-$subname";
}
}
closedir(SUBDIR);
} else {
# db entry has trailing slash...
if (!defined($db_maildirs{"$name/"})) {
print "marking $maildir_path/$name for deletion.\n";
$directories{"$name"} = $name;
}
}
}
closedir(DIR);
print "Ctrl-C in 5 seconds to abort before removal starts...\n";
sleep 5;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
# yyyymmddhhmm
my $tstamp = sprintf("%04d%02d%02d%02d%02d", $year+1900, $mon+1, $mday, $hour, $min);
# compare two arrays and erase maildirs not found in database
chdir $maildir_path || die "Can't change to maildir '$maildir_path': $!\n";;
my @args;
foreach my $maildir (keys(%directories)) {
my $archive = "$archdir/$directories{$maildir}-$tstamp.tgz";
# quick permissions check
open(TOUCH, ">$archive") || die "Can't create archive file $archive: $!\n";
close(TOUCH);
print "Archiving $maildir\n";
@args = ($archcmd, "cvzf", $archive, $maildir);
system(@args) == 0 or die "Creating archive for $maildir failed: $?"
rmtree($maildir);
print localtime() . " $maildir has been deleted.\n";
}

@ -1,167 +0,0 @@
#!/usr/bin/perl
#
# Generate an 'everybody' alias for a domain.
#
# Create the file /etc/mkeveryone.conf
# chmod 640 /etc/mkeveryone.conf
# Example of mkeveryone.conf
#
# userid=postfix
# passwd=postfix
# db=postfix
# host=localhost
# port=3306
# domain=domain.tld
# target=everybody@domain.tld
# ignore=vacation@domain.tld
# ignore=spam@domain.tld
# ignore=newsletter@domain.tld
# ignore=root@domain.tld
#
# Save this file in, for example, /usr/local/sbin/mkeveryone.pl
# chmod 750 /usr/local/sbin/mkeveryone.pl
#
# Run the script!
#
use DBI;
use Time::Local;
use POSIX qw(EAGAIN);
use Fcntl;
use IO;
use IO::File;
my $timeNow=time();
my $DATFILE = "/etc/mkeveryone.conf";
my $FILEHANDLE = "";
# database information
my $db="postfix";
my $host="localhost";
my $port="3306";
my $userid="postfix";
my $passwd="postfix";
my $domain="domain.tld";
my $target="everyone@$domain";
my @ignore;
my @dest;
open (FILEHANDLE, $DATFILE);
while ( $LINE = <FILEHANDLE> ) {
if ( length $LINE > 0 ) {
chomp $LINE;
$RETURNCODE = 0;
SWITCH: {
$LINE =~ /^ignore/i and do {
$LINE =~ s/^ignore// && $LINE =~ s/=// && $LINE =~ s/^ //g;
@ignore = (@ignore,$LINE);
};
$LINE =~ /^userid/i and do {
# Userid found.";
$LINE =~ s/^userid// && $LINE =~ s/=// && $LINE =~ s/^ //g;
$userid = $LINE;
};
$LINE =~ /^passwd/i and do {
# Passwd found.";
$LINE =~ s/^passwd// && $LINE =~ s/=// && $LINE =~ s/^ //g;
$passwd = $LINE;
};
$LINE =~ /^db/i and do {
# Database found.";
$LINE =~ s/^db// && $LINE =~ s/=// && $LINE =~ s/^ //g;
$db = $LINE;
};
$LINE =~ /^host/i and do {
# Database host found.";
$LINE =~ s/^host// && $LINE =~ s/=// && $LINE =~ s/^ //g;
$host = $LINE;
};
$LINE =~ /^port/i and do {
# Database host found.";
$LINE =~ s/^port// && $LINE =~ s/=// && $LINE =~ s/^ //g;
$port = $LINE;
};
$LINE =~ /^target/i and do {
# Database host found.";
$LINE =~ s/^target// && $LINE =~ s/=// && $LINE =~ s/^ //g;
$target = $LINE;
};
$LINE =~ /^domain/i and do {
# Database host found.";
$LINE =~ s/^domain// && $LINE =~ s/=// && $LINE =~ s/^ //g;
$domain = $LINE;
};
}
}
}
print "Connecting to database $db on $host:$port...\n\r";
print "Target email address is $target...\n\r";
my $connectionInfo="DBI:mysql:database=$db;$host:$port";
# make connection to database
$dbh = DBI->connect($connectionInfo,$userid,$passwd);
# Delete the old message...prepare and execute query
$query = "SELECT username FROM mailbox WHERE domain='$domain';";
$sth = $dbh->prepare($query);
$sth->execute();
# assign fields to variables
$sth->bind_columns(\$username);
my $ign="false";
while($sth->fetch()) {
$ign = "false";
foreach $ignored ( @ignore ) {
if ( $username eq $ignored ){
$ign = "true";
}
}
if ( $ign eq "false" ) {
@dest = (@dest,$username);
}
}
# Delete the old aliases...prepare and execute query
$query = "DELETE FROM alias WHERE address='$target';";
$sth = $dbh->prepare($query);
$sth->execute();
print "Record deleted from the database.\r\n";
$sth->finish();
$goto = join(",",@dest);
print "$goto\n\r\n\r";
# Insert the new message...prepare and execute query
$query = "INSERT INTO alias (address,goto,domain,created,modified) VALUES ('$target','$goto','$domain',now(),now());";
$sth = $dbh->prepare($query);
$sth->execute();
print "Record added to the database.\r\n";
$sth->finish();
# disconnect from databse
$dbh->disconnect;

@ -1,111 +0,0 @@
#!/usr/bin/perl
#
##
## pfa_maildir_cleanup.pl
##
## (c) 2004 by Stephen Fulton (sfulton@esoteric.ca)
##
## based on a script by Petr Znojemsky (thanks!)
##
## Simple script to remove maildirs/domains not listed in a MySQL database.
## Set up for use with those using PostfixAdmin, but can be adapted.
##
## Edit the variables between the ##EDIT## to match your setup.
##
## USE AT YOUR OWN RISK. I ASSUME NO RESPONSIBILITY.
##
use DBI;
use File::Path;
##EDIT##
$root_path = "/home/mail";
$logfile = "/var/log/removed_maildirs.log";
$db_host = "localhost";
$db_database = "database";
$db_user = "username";
$db_password = 'password';
##END EDIT##
$connectionInfo = "DBI:mysql:database=$db_database;$db_host:3306";
## Read a list of domain directories in the root path /remote/mail1
opendir(DIRHANDLE, $root_path) || die "Cannot access directory $maildir_path: $!";
my @directories = ();
foreach $directory (sort readdir(DIRHANDLE)) {
push (@directories, $directory);
}
closedir(DIRHANDLE);
## Strip the "." and ".." from the directories array
($dot, $doubledot, @directories) = @directories;
## For each of the domain directories..
foreach $domain_dir (@directories) {
$complete_domain_path = "$root_path/$domain_dir";
## Get a list of user directories within each domain directory...
opendir(DOMAINHANDLE, $complete_domain_path) || die "Cannot access directory $complete_domain_path: $!";
my @user_directories = ();
foreach $dir (sort readdir(DOMAINHANDLE)) {
push(@user_directories, $dir);
}
close(DOMAINHANDLE);
## Now remove any "." or ".." directory entries and construct a domain/maildir variable
## valid for one iteration of loop.
foreach $user_directory (@user_directories) {
if( not($user_directory eq '..') && not($user_directory eq '.') ) {
$short_user_dir = "$domain_dir/$user_directory/";
## Here is where the $short_user_dir is compared against the DB entry.
$dbh = DBI->connect($connectionInfo,$db_user,$db_password);
$user_query = "SELECT maildir FROM mailbox WHERE maildir = '$short_user_dir'";
$sth = $dbh->prepare($user_query);
$rows = $sth->execute();
## If there are no rows that match, then directory is orphaned and can
## be deleted.
if($rows == 0) {
$maildir_path = "$root_path/$short_user_dir";
open(INFO, ">>$logfile") || die "Cannot write to the logfile: $logfile.";
rmtree($maildir_path);
print INFO localtime()." Maildir ".$maildir_path." has been deleted.\n";
(INFO);
}
$sth->finish;
$dbh->disconnect;
}
}
$dbh2 = DBI->connect($connectionInfo,$db_user,$db_password);
$domain_query = "SELECT domain FROM domain WHERE domain = '$domain_dir'";
$sth2 = $dbh2->prepare($domain_query);
$domain_rows = $sth2->execute();
if($domain_rows == 0) {
open(INFO, ">>$logfile") || die "Cannot write to the logfile: $logfile.";
rmtree($complete_domain_path);
print INFO localtime()." Domain directory ".$complete_domain_path." has been deleted.\n";
close(INFO);
}
$sth2->finish;
$dbh2->disconnect;
}

@ -1,62 +0,0 @@
#!/bin/sh
# Example script for removing a Maildir domain top-level folder
# from a Courier-IMAP virtual mail hierarchy.
# The script only looks at argument 1, assuming that it
# indicates the relative name of a domain, such as
# "somedomain.com". If $basedir/somedomain.com exists, it will
# be removed.
# The script will not actually delete the directory. I moves it
# to a special directory which may once in a while be cleaned up
# by the system administrator.
# This script should be run as the user which owns the maildirs. If
# the script is actually run by the apache user (e.g. through PHP),
# then you could use "sudo" to grant apache the rights to run
# this script as the relevant user.
# Assume this script has been saved as
# /usr/local/bin/postfixadmin-domain-postdeletion.sh and has been
# made executable. Now, an example /etc/sudoers line:
# apache ALL=(courier) NOPASSWD: /usr/local/bin/postfixadmin-domain-postdeletion.sh
# The line states that the apache user may run the script as the
# user "courier" without providing a password.
# Change this to where you keep your virtual mail users' maildirs.
basedir=/var/spool/maildirs
# Change this to where you would like deleted maildirs to reside.
trashbase=/var/spool/deleted-maildirs
if [ `echo $1 | fgrep '..'` ]; then
echo "First argument contained a double-dot sequence; bailing out."
exit 1
fi
if [ ! -e "$trashbase" ]; then
echo "trashbase '$trashbase' does not exist; bailing out."
exit 1
fi
trashdir="${trashbase}/`date +%F_%T`_$1"
domaindir="${basedir}/$1"
if [ ! -e "$domaindir" ]; then
echo "Directory '$domaindir' does not exits; nothing to do."
exit 0;
fi
if [ ! -d "$domaindir" ]; then
echo "'$domaindir' is not a directory; bailing out."
exit 1
fi
if [ -e "$trashdir" ]; then
echo "Directory '$trashdir' already exits; bailing out."
exit 1;
fi
mv $domaindir $trashdir
exit $?

@ -1,71 +0,0 @@
#!/bin/sh
# Example script for adding a Maildir to a Courier-IMAP virtual mail
# hierarchy.
# The script only looks at argument 3, assuming that it
# indicates the relative name of a maildir, such as
# "somedomain.com/peter/".
# This script should be run as the user which owns the maildirs. If
# the script is actually run by the apache user (e.g. through PHP),
# then you could use "sudo" to grant apache the rights to run
# this script as the relevant user.
# Assume this script has been saved as
# /usr/local/bin/postfixadmin-mailbox-postcreation.sh and has been
# made executable. Now, an example /etc/sudoers line:
# apache ALL=(courier) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postcreation.sh
# The line states that the apache user may run the script as the
# user "courier" without providing a password.
# Change this to where you keep your virtual mail users' maildirs.
basedir=/var/spool/maildirs
if [ ! -e "$basedir" ]; then
echo "$0: basedir '$basedir' does not exist; bailing out."
exit 1
fi
if [ `echo $3 | fgrep '..'` ]; then
echo "$0: An argument contained a double-dot sequence; bailing out."
exit 1
fi
maildir="${basedir}/$3"
parent=`dirname "$maildir"`
if [ ! -d "$parent" ]; then
if [ -e "$parent" ]; then
echo "$0: strange - directory '$parent' exists, but is not a directory; bailing out."
exit 1
else
mkdir -p "${parent}"
if [ $? -ne 0 ]; then
echo "$0: mkdir -p '$parent' returned non-zero; bailing out."
exit 1
fi
fi
fi
if [ -e "$maildir" ]; then
echo "$0: Directory '$maildir' already exists! bailing out"
exit 1
fi
# try looking for maildirmake ...
MDM=`which maildirmake || which courier-maildirmake`
if [ "x${MDM}" = "x" ]; then
echo "Couldn't find maildirmake or courier-maildirmake in your PATH etc (via which)" >/dev/stderr
exit 1
fi
"${MDM}" "${maildir}"
if [ ! -d "$maildir" ]; then
echo "$0: maildirmake didn't produce a directory; bailing out."
exit 1
fi
exit 0

@ -1,77 +0,0 @@
#!/bin/sh
# Example script for removing a Maildir from a Courier-IMAP virtual mail
# hierarchy.
# The script looks at arguments 1 and 2, assuming that they
# indicate username and domain, respectively.
# The script will not actually delete the maildir. I moves it
# to a special directory which may once in a while be cleaned up
# by the system administrator.
# This script should be run as the user which owns the maildirs. If
# the script is actually run by the apache user (e.g. through PHP),
# then you could use "sudo" to grant apache the rights to run
# this script as the relevant user.
# Assume this script has been saved as
# /usr/local/bin/postfixadmin-mailbox-postdeletion.sh and has been
# made executable. Now, an example /etc/sudoers line:
# apache ALL=(courier) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postdeletion.sh
# The line states that the apache user may run the script as the
# user "courier" without providing a password.
# Change this to where you keep your virtual mail users' maildirs.
basedir=/var/spool/maildirs
# Change this to where you would like deleted maildirs to reside.
trashbase=/var/spool/deleted-maildirs
if [ ! -e "$trashbase" ]; then
echo "trashbase '$trashbase' does not exist; bailing out."
exit 1
fi
if [ `echo $1 | fgrep '..'` ]; then
echo "First argument contained a double-dot sequence; bailing out."
exit 1
fi
if [ `echo $2 | fgrep '..'` ]; then
echo "First argument contained a double-dot sequence; bailing out."
exit 1
fi
subdir=`echo "$1" | sed 's/@.*//'`
maildir="${basedir}/$2/${subdir}"
trashdir="${trashbase}/$2/`date +%F_%T`_${subdir}"
parent=`dirname "$trashdir"`
if [ ! -d "$parent" ]; then
if [ -e "$parent" ]; then
echo "Strainge - directory '$parent' exists, but is not a directory."
echo "Bailing out."
exit 1
else
mkdir -p "$parent"
if [ $? -ne 0 ]; then
echo "mkdir -p '$parent' returned non-zero; bailing out."
exit 1
fi
fi
fi
if [ ! -e "$maildir" ]; then
echo "maildir '$maildir' does not exist; nothing to do."
exit 1
fi
if [ -e "$trashdir" ]; then
echo "trashdir '$trashdir' already exists; bailing out."
exit 1
fi
mv $maildir $trashdir
exit $?

@ -1,151 +0,0 @@
#!/usr/bin/perl
# vim:ts=4:sw=4:et
# Virtual quota_usage 0.3
# Contributed to Postfixadmin by Jose Nilton <jniltinho@gmail.com>
#
# See also : http://www.russelldare.net/media/perl/dirsizeSource.pdf
# License: GPL v2.
# Usage:
# perl quota_usage.pl --list
# perl quota_usage.pl --list --addmysql
# for add mysql database postfix
#
# Requirements - the following perl modules are required:
# DBD::Pg or DBD::mysql; perl perl-DBD-mysql perl-DBD (may be named differently depending on your platform).
# and the 'du' binary in $ENV{'PATH'} (see below).
#
# You will need to modify the postfix DATABASE to add a quota_usage column.
# Mysql:
# ALTER TABLE mailbox ADD quota_usage INT(11) NOT NULL DEFAULT '0' AFTER modified,
# ADD quota_usage_date DATE NOT NULL DEFAULT '0000-00-00' AFTER quota_usage;
# PostgreSQL:
# ALTER TABLE mailbox ADD COLUMN quota_usage INTEGER NOT NULL DEFAULT 0;
# ALTER TABLE mailbox ADD COLUMN quota_usage_date DATE NOT NULL DEFAULT current_date;
#
use strict;
use warnings;
use File::Path;
use DBI;
use Getopt::Long;
##EDIT##
my $db_host = 'localhost';
my $db_database = 'postfix';
my $db_user = 'postfix';
my $db_password = '123456';
my $root_path = '/home/vmail';
# Pg or mysql
my $db_type = 'mysql';
##END EDIT##
(help()) if (!$ARGV[0]);
$ENV{'PATH'} = "/sbin:/bin:/usr/sbin:/usr/bin";
my($domain_dir, $full_domain_dir, $user_dir, $usage, $email, $sql, $dbh);
my $list = 0;
my $insert_db = 0;
my $total_mailbox = 0;
my $total_domain = 0;
GetOptions ('l|list' => \$list, 'i|addmysql' => \$insert_db, 'help|h|man' => \&help) or (help());
(list_quota_usage()) if ($list == 1 || $insert_db == 1 );
sub list_quota_usage {
opendir(DOMAINDIR, $root_path) or die ("Unable to access directory '$root_path' ($!)");
if($insert_db == 1){
$dbh = DBI->connect("DBI:$db_type:database=$db_database;host=$db_host", $db_user, $db_password) or die ("cannot connect the database");
execSql("UPDATE mailbox set quota_usage = 0");
}
foreach $domain_dir (sort readdir DOMAINDIR) {
next if $domain_dir =~ /^\./; # skip dotted dirs
$full_domain_dir = "$root_path/$domain_dir"; #print "$full_domain_dir\n";
$total_domain++;
opendir(USERDIR, $full_domain_dir) or die ("Unable to access directory '$full_domain_dir' ($!)");
foreach $user_dir (sort readdir USERDIR) {
next if $user_dir =~ /^\./; # skip dotted dirs
$email = "$user_dir\@$domain_dir";
$total_mailbox++;
my $i = `du -0 --summarize $full_domain_dir/$user_dir`;
($usage) = split(" ", $i);
if ($usage < 100) {
$usage = 0;
} elsif ($usage < 1000) {
$usage = 1;
} else {
$usage = $usage + 500;
$usage = int $usage / 1000;
}
if($insert_db == 1){execSql("UPDATE mailbox set quota_usage = $usage, quota_usage_date = CAST(NOW() AS DATE) WHERE username = '$email'");}
print_list() if ($list == 1);
}
}
close(DOMAINDIR);
close(USERDIR);
(print_total()) if ($list == 1);
}
sub execSql {
my $sql = shift;
my $ex;
$ex = $dbh->do($sql) or die ("error when running $sql");
}
sub print_total{
print "---------------------------------------------------------\n";
print "TOTAL DOMAIN\t\t\t\tTOTAL MAILBOX\n";
print "---------------------------------------------------------\n";
print "$total_domain\t\t\t\t\t\t$total_mailbox\n";
}
sub print_list {
format STDOUT_TOP =
Report of Quota Used
---------------------------------------------------------
EMAIL QUOTA USED
---------------------------------------------------------
.
format =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<
$email, "$usage MB"
.
write;
}
sub help {
print "$0 [options...]\n";
print "-l|--list List quota used\n";
print "-i|--addmysql For insert quota used in database mysql\n";
}

@ -1,38 +0,0 @@
Installing the postfixadmin Plugin
======================================
Requirements:
=============
- PHP 5.[234].* with php5-xmlrpc installed (if available; it should be available by default anyway)
- http access to a local/remote postfixadmin interface
- Zend Framework (1.12.x) - needs adding to the include path within common.php,
or installing in a system include path directory (e.g. /usr/share/php)
(e.g. from within the directory containing this file ...
wget https://packages.zendframework.com/releases/ZendFramework-1.12.3/ZendFramework-1.12.3-minimal.tar.gz
tar -zxf ZendFramework-1.12.3-minimal.tar.gz
mv ZendFramework-1.12.3-minimal/library/Zend . )
NOTE: This plugin is _not compatible_ with Zend Framework version 2.x.
Installation :
==============
- Copy this code into the Squirrelmail plugins directory - your life will be easiest if it's in a directory called 'postfixadmin'
- Install Zend Framework (see above under Requirements for example)
- Edit config.php and specify the remote URL for the Postfixadmin XmlRpc service.
- Edit common.php and (if you need to) change the include path(s) so they are correct.
- Edit the remote Postfixadmin's XmlRpc service config file and ensure 'xmlrpc_enabled' is set to boolean true.
- Enable the plugin through 'squirrelmail-configure' or 'config/conf.pl'.
Choose option 8 and move the plugin from the "Available Plugins"
category to the "Installed Plugins" category. Save and exit.
Security :
==========
- The XmlRpc client needs to get the user's mailbox password before it will be able to connect to the
XmlRpc server (postfixadmin). The plugin prompts the user for their mailbox password, and caches it in their session
($_SESSION['password']). This password is then sent once on every page load to the remote XmlRpc server.
- You should consider doing any of the following :
- Using https if the server and client are on seperate servers. This will probably require a signed certificate etc, and may require changes to the Zend_XmlRpc_Client's HttpClient.
- Using something like stunnel to encrypt traffic between server(s).

@ -1,40 +0,0 @@
2007/03/29 :
Before I (David Goodwin) customised this plugin, it contained the following within all
files as a header.
/****************************************************************************************
Author ......... Florian Kimmerl
Contact ........ info@spacekoeln.de
Home Site ...... http://www.spacekoeln.de/
Program ........ postfixadmin
Purpose ........ Allows you to change your postfixadmin settings within squirrelmail
*************************************************************************************
The Original Code is Postfix Admin.
The Initial Developer of the Original Code is Mischa Peters .
Portions created by Mischa Peters are Copyright (c) 2002, 2003, 2004.
All Rights Reserved.
Contributor(s):
This project includes work by Mischa Peters and others that is:
Copyright (c) 2002,2003,2004 Mischa Peters
All rights reserved.
****************************************************************************************/
Contacting the author provided no success, so I took over maintainership.
Please note:
1) Changes made by myself (David Goodwin) will be licensed under the GPL
2) PostfixAdmin has itself been relicensed under the GPL; however this took place _after_
this plugin was written.
3) Squirrelmail itself is released under http://squirrelmail.org/wiki/SquirrelMailGPL (GPL)
The GNU public license can be found online at :
http://www.gnu.org/licenses/gpl.txt

@ -1,31 +0,0 @@
# Squirrelmail Plugin Postfixadmin
The Postfixadmin SquirrelMail plugin let users change their virtual alias,
vacation status/message and password
Your users can therefore use this plugin within Squirrelmail to :
* Turn vacation on/off
* Change their email password
* Setup forwarding rules
Note, this plugin does not require access to the Postfixadmin database. It communicates with Postfixadmin using the XMLRPC protocol.
## Notes
* We now depend upon the Zend Framework (preferably v1.9.x at the time of writing) (Download from http://framework.zend.com/download/latest - the minimal one should be sufficient)
* Traffic to the XmlRpc interface needs encrypting (e.g. https) - this is something _you_ need to do
* When trying to use the plugin, the user will be prompted to enter their mailbox password - this is necessary to authenticate with the remote XmlRpc? interface
## REQUIREMENTS
* SquirrelMail 1.4x
* PostfixAdmin version 3 or higher.
* PHP 5.4+ with XMLRPC support

@ -1,51 +0,0 @@
<?php
// vim:ts=4:sw=4:et
ini_set('include_path', get_include_path() . ':' . dirname(__FILE__));
@include_once('Zend/Version.php');
if (!class_exists('Zend_Version', false)) {
die("Zend Framework not found. Please check the INSTALL File.");
}
chdir("..");
if (!defined('SM_PATH')) {
define('SM_PATH', '../');
}
$config_file = dirname(__FILE__ ) . '/config.php';
$validate_file = dirname(__FILE__) . '/../include/validate.php';
if (!file_exists($config_file)) {
die("$config_file is missing");
}
include_once($config_file);
include_once(dirname(__FILE__) . '/functions.inc.php');
if (file_exists($validate_file)) {
include_once($validate_file);
} else {
$validate_file = SM_PATH . '/src/validate.php';
if (file_exists($validate_file)) {
include_once($validate_file);
}
}
include_once(SM_PATH . 'functions/page_header.php');
include_once(SM_PATH . 'functions/display_messages.php');
include_once(SM_PATH . 'functions/imap.php');
include_if_exists(SM_PATH . 'functions/array.php');
if (file_exists(SM_PATH . 'src/load_prefs.php')) {
include_once(SM_PATH . 'src/load_prefs.php');
} else {
include_if_exists(SM_PATH . 'include/load_prefs.php');
}
// overwrite squirrelmail's content type to utf8...
header("Content-Type: text/html; charset=utf8");
//global $VACCONFMESSAGE;
bindtextdomain('postfixadmin', dirname(__FILE__) . '/postfixadmin/locale');
textdomain('postfixadmin');

@ -1,22 +0,0 @@
<?php
$CONF = array();
$CONF['xmlrpc_url'] = 'http://postfixadmin.local/postfixadmin/xmlrpc.php';
// Virtual Vacation
// If you use virtual vacation for you mailbox users set this to 'true'.
// NOTE: Make sure that you install the vacation module!!
//$AllowVacation = true; // true or false
global $AllowVacation;
$AllowVacation = true;
// Change Password
// Enables user to change the POP3/IMAP Password.
//$AllowChangePass = true; // true or false
global $AllowChangePass;
$AllowChangePass = true;
// Minimum password length - set to Zero to not care, otherwise the number of
// characters a password must be longer than.
$CONF['min_password_length'] = 5;

@ -1,20 +0,0 @@
Squirrelmail PostfixAdmin Plugin for Debian
===========================================
After installing the package, you will need to :
1) Edit the config.inc.php file to point to the PostfixAdmin server.
2) Ensure the xmlrpc interface is available and enabled on the Postfixadmin server
3) Run the squirrelmail-configure script.
Where to get help
=================
See http://squirrelmail-postfixadmin.palepurple.co.uk
Try also : david [at] pale purple dot co dot uk
Or #postfixadmin on irc.freenode.net might be a good bet.

@ -1,27 +0,0 @@
squirrelmail-postfixadmin (2.3.0) stable; urgency=low
* Using XMLRPC backend (no SQL here)
-- David Goodwin <david.goodwin@palepurple.co.uk> Mon, 01 Feb 2010 09:56:00 +0000
squirrelmail-postfixadmin (2.2.0) stable; urgency=low
* Changed DB backend to use prepared statements
* Changed vacation handling to match that of Postfixadmin (vacation.active
etc)
* Changed vacation page to support UTF8
-- David Goodwin <david.goodwin@palepurple.co.uk> Wed, 20 Aug 2008 15:25:00 +0000
squirrelmail-postfixadmin (2.1.1-1) stable; urgency=low
* Add NL language support
* Better db error logging (e.g. if wrong mdb2 driver specified etc)
-- David Goodwin <david.goodwin@palepurple.co.uk> Wed, 12 Dec 2007 16:00:00 +0000
squirrelmail-postfixadmin (2.1.0-1) stable; urgency=low
* Initial release.
-- David Goodwin <david.goodwin@palepurple.co.uk> Thu, 8 Nov 2007 20:00:00 +0000

@ -1 +0,0 @@
/etc/squirrelmail/plugins/postfixadmin-config.php

@ -1,19 +0,0 @@
Source: squirrelmail-postfixadmin
Section: mail
Priority: optional
Maintainer: David Goodwin <david.goodwin@palepurple.co.uk>
Standards-Version: 3.6.1
Package: squirrelmail-postfixadmin
Architecture: all
Depends: squirrelmail, php-pear
Suggests: postfixadmin
Description: Plugin for Squirrelmail to integrate with Postfixadmin
Postfixadmin is a web based interface for managing mail domains
and users. This package integrates Squirrelmail with it.
Users can change their password, forwarding and vacation settings
from within Squirrelmail when this package is installed, and
enabled through the ./squirrelmail-configure command.
.
For further information see
http://squirrelmail-postfixadmin.palepurple.co.uk

@ -1,11 +0,0 @@
This package was debianized by David Goodwin <david@palepurple.co.uk>
2007/11/08
It was downloaded from: http://squirremail-postfixadmin.palepurple.co.uk
Upstream Author(s): n/a
Copyright:
Copyright (C) 2007+ by David Goodwin <david@palepurple.co.uk>
License: GPL v2+

@ -1,4 +0,0 @@
LICENSE.txt
README
INSTALL
debian/README.Debian

@ -1 +0,0 @@
squirrelmail-postfixadmin_2.2.0_all.deb mail optional

@ -1,3 +0,0 @@
usr/share/squirrelmail/plugins/postfixadmin
usr/share/doc/squirrelmail-postfixadmin
etc/squirrelmail/plugins

@ -1,5 +0,0 @@
#!/bin/sh
echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
echo "WARNING: You need to read /usr/share/doc/squirrelmail-postfixadmin/README.Debian!"
echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

@ -1,56 +0,0 @@
#!/usr/bin/make -f
# debian/rules makefile for squirrelmail
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
build: build-stamp
build-stamp:
dh_testdir
clean:
dh_testdir
dh_testroot
dh_clean
install: build
$(checkdir)
dh_testdir
dh_testroot
dh_clean -k
dh_installdirs
dh_install
mkdir -p debian/tmp/usr/share/squirrelmail/plugins/postfixadmin
cp -a *.php version debian/tmp/usr/share/squirrelmail/plugins/postfixadmin
cp -a locale debian/tmp/usr/share/squirrelmail/plugins/postfixadmin
cp -a po debian/tmp/usr/share/squirrelmail/plugins/postfixadmin
mkdir -p debian/tmp/etc/squirrelmail/plugins/
cp -a *.sample debian/tmp/etc/squirrelmail/plugins/postfixadmin-config.php
mkdir -p debian/tmp/DEBIAN
cp debian/postinst debian/tmp/DEBIAN/postinst
chmod 555 debian/tmp/DEBIAN/postinst
ln -s /etc/squirrelmail/plugins/postfixadmin-config.php debian/tmp/usr/share/squirrelmail/plugins/postfixadmin/config.php
find debian/tmp -name .svn | xargs -r rm -r
# Build architecture-independent files here.
binary-indep: build install
dh_testdir
dh_testroot
dh_installdebconf
dh_installdocs -X.svn
dh_installexamples
dh_installman
dh_installcron
dh_link
dh_compress
dh_fixperms -X/var
dh_installdeb
dh_gencontrol
dh_md5sums
dh_builddeb
# Build architecture-dependent files here.
binary-arch:
binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

@ -1,96 +0,0 @@
<?php
/**
* Postfixadmin (http://postfixadmin.sf.net) integration with Squirrelmail.
* See http://squirrelmail-postfixadmin.palepurple.co.uk
* @author David Goodwin and many others
*/
function do_header() {
global $color;
displayPageHeader($color, 'None');
}
function do_footer() {
echo "</body></html>";
}
function _display_password_form() {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
do_header('Postfixadmin Squirrelmail - Login');
echo _('The PostfixAdmin plugin needs your current mailbox password');
echo "<form action='' method='post'>";
echo _('Password for');
echo " " . $_SESSION['username'] . " :";
echo "<input type='password' name='password' value=''>";
echo "<input type='submit' value='" . _('Submit') . "'></form>";
do_footer();
}
/**
* This returns a Zend_XmlRpc_Client instance - unless we can't log you in...
*/
function get_xmlrpc() {
global $CONF;
require_once('Zend/XmlRpc/Client.php');
$client = new Zend_XmlRpc_Client($CONF['xmlrpc_url']);
$http_client = $client->getHttpClient();
$http_client->setCookieJar();
$login_object = $client->getProxy('login');
if (empty($_SESSION['password'])) {
if (empty($_POST['password'])) {
_display_password_form();
exit(0);
} else {
try {
$success = $login_object->login($_SESSION['username'], $_POST['password']);
} catch (Exception $e) {
//var_dump($client->getHttpClient()->getLastResponse()->getBody());
error_log("Failed to login to xmlrpc instance - " . $e->getMessage());
die('Failed to login to xmlrpc instance');
}
if ($success) {
$_SESSION['password'] = $_POST['password'];
// reload the current page as a GET request.
header("Location: {$_SERVER['REQUEST_URI']}");
exit(0);
} else {
_display_password_form();
exit(0);
}
}
} else {
$success = $login_object->login($_SESSION['username'], $_SESSION['password']);
}
if (!$success) {
unset($_SESSION['password']);
die("Invalid details cached... refresh this page and re-enter your mailbox password");
}
return $client;
}
function include_if_exists($filename) {
if (file_exists($filename)) {
include_once($filename);
}
return;
}
global $optmode;
$optmode = 'display';
//
// check_email
// Action: Checks if email is valid and returns TRUE if this is the case.
// Call: check_email (string email)
//
function check_email($email) {
$return = filter_var($email, FILTER_VALIDATE_EMAIL);
if ($return === false) {
return false;
}
return true;
}

@ -1,25 +0,0 @@
<?php
/****************************************************************************************
Author ......... Florian Kimmerl
Contact ........ info@spacekoeln.de
Home Site ...... http://www.spacekoeln.de/
Program ........ postfixadmin
Version ........ 0.3-1.4
Purpose ........ Allows you to change your postfixadmin settings within squirrelmail
/**
* index.php
*
* Copyright (c) 1999-2003 The SquirrelMail Project Team
* Licensed under the GNU GPL. For full terms see the file COPYING.
*
* This file simply takes any attempt to view source files and sends those
* people to the login screen. At this point no attempt is made to see if
* the person is logged or not.
*
*
****************************************************************************************/
header("Location: ../../index.php");

@ -1,6 +0,0 @@
#!/bin/bash
for f in $(find . -name postfixadmin.po)
do
msgfmt -o $(dirname $f)/postfixadmin.mo $f
done

@ -1,132 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2004-01-29 17:35+0100\n"
"PO-Revision-Date: 2007-07-20 20:46+0100\n"
"Last-Translator: Michael Heca <michael.heca@gmail.com>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-2\n"
"Content-Transfer-Encoding: 8bit\n"
#: setup.php
msgid "Forwarding"
msgstr "Pøesmìrování"
msgid "Here you can create and edit E-Mail forwards."
msgstr "Zde mù¾ete vytvoøit a nastavit pøesmìrování"
msgid "Set an OUT OF OFFICE message or auto responder for your mail."
msgstr "Zde mù¾ete nastavit automatickou odpovìd, pokud nebudete k zasti¾ení."
msgid "Change your mailbox password."
msgstr "Zmìnít heslo k Va¹emu e-mailovému úètu"
#: postfixadmin_changepass.php
msgid "Alias"
msgstr "Úèet"
msgid "Change Password"
msgstr "Zmìnit heslo"
msgid "Change your login password"
msgstr "Zmìnít heslo k Va¹emu e-mailovému úètu"
#: postfixadmin_forward.php
msgid "Edit Alias"
msgstr "Editace adresy pro pøesmìrování"
msgid "Edit an alias* for your domain.<br />One entry per line."
msgstr "Editace pøesmìrování pro Vá¹ úèet. <br/> Ka¾dá adresa na novém øádku."
msgid "The email address that you have entered is not valid:"
msgstr "Zadaná e-mailová adresa je chybná:"
msgid "Unable to locate alias!"
msgstr "Neni mo¾né nalézt úèet!"
msgid "Unable to modify the alias!"
msgstr "Není mo¾né zmìnit úèet!"
msgid "*Additional forward-aliase always recieve messages BBC!"
msgstr "Dal¹í aliasy dostanou e-mail jako BBC!"
msgid "Alias successfully changend!"
msgstr "Pøesmìrování bylo zmìnìno!"
msgid "To remove an alias, simply delete it's line from the text box."
msgstr "Pro odstranení pøesmìrování sma¾te v¹echny øádky v textovém boxu."
#: postfixadmin_vacation.php
msgid "Auto Response"
msgstr "Automatická odpovìï"
msgid "Going Away"
msgstr "Jsem mimo"
msgid "Coming Back"
msgstr "Jsem zpìt"
msgid "Options"
msgstr "Nastavení"
msgid "Out of Office"
msgstr "Mimo kanceláø"
msgid "Subject"
msgstr "Pøedmìt"
msgid "Body"
msgstr "Tìlo mailu"
msgid "Your auto response has been removed!"
msgstr "Va¹e automatická odpovìï byla odstranìna!"
msgid "Your auto response has been set!"
msgstr "Va¹e automatická odpovìï byla nastavena!"
msgid "You already have an auto response configured!"
msgstr "U¾ máte nastavenu automatickou odpovìï!"
#: postfixadmin_changepass.php:81
#: postfixadmin_changepass.php:87
msgid "The passwords that you supplied don't match!<br />Or are empty!"
msgstr "Zadaná hesla nejsou stejná a nebo jsou prázdná!"
#: postfixadmin_forward.php:70
#: postfixadmin_forward.php:152
msgid "To"
msgstr "Komu"
#: postfixadmin_changepass.php:101
msgid "Unable to change your password!"
msgstr "Není mo¾né zmìnit heslo!"
#: postfixadmin_changepass.php:75
msgid "You didn't supply your current password!"
msgstr "Stávající heslo neodpovídá!"
#: postfixadmin_changepass.php:96
msgid "Your password has been changed!"
msgstr "Va¹e heslo bylo zmìnìno!"
msgid "Password current"
msgstr "Stávající heslo"
msgid "Password new"
msgstr "Nové heslo"
msgid "Password new again"
msgstr "Nové heslo znovu"
msgid "Please sign out and log back again with your new password!"
msgstr "Prosím odhla¹te se a pøihla¹te se s novým heslem!"
msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
msgstr "Nebudy k zasti¾ení od <date> do <date>. Pro naléhané po¾adavky prosím kontaktujte <contact person>."

@ -1,127 +0,0 @@
# Danish translation for Squirrelmail Plugin Postfixadmin.
# Copyright (C) 2004 Florian Kimmerl, 2007 David Goodwin
# This file is distributed under the same license as the Squirrelmail Plugin Postfixadmin package.
# Jesper R. Meyer <jrm@upthere.dk>, 2007.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.4.3\n"
"POT-Creation-Date: 2004-01-29 17:35+0100\n"
"PO-Revision-Date: 2007-11-09 16:07+0100\n"
"Last-Translator: JESPER MEYER <jrm@upthere.dk>\n"
"Language-Team: DANISH <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: setup.php
msgid "Forwarding"
msgstr "Videresending"
msgid "Here you can create and edit E-Mail forwards."
msgstr "Her kan du oprette og ændre email-videresendinger."
msgid "Set an OUT OF OFFICE message or auto responder for your mail."
msgstr "Tilføj en 'ikke tilstede' besked eller et autosvar til din emailadresse."
msgid "Change your mailbox password."
msgstr "Ændre adgangskoden til din postboks"
#: postfixadmin_changepass.php
msgid "Alias"
msgstr "Alias"
msgid "Change Password"
msgstr "Ændre adgangskode"
msgid "Change your login password"
msgstr "Ændre din login-adgangskode"
#: postfixadmin_forward.php
msgid "Edit Alias"
msgstr "Rediger alias"
msgid "Edit an alias* for your domain.<br />One entry per line."
msgstr "Rediger et alias* for dit domæne.<br />En modtager pr. linje."
msgid "The email address that you have entered is not valid:"
msgstr "Emailadressen du angav er ugyldig"
msgid "Unable to locate alias!"
msgstr "Aliaset eksistere ikke!"
msgid "Unable to modify the alias!"
msgstr "Kunne ikke ændre aliaset!"
msgid "*Additional forward-aliase always recieve messages BBC!"
msgstr "*Eksta vidersendingsalias modtager altid meddelelser BCC!"
msgid "Alias successfully changend!"
msgstr "Alias ændret!"
#: postfixadmin_vacation.php
msgid "Auto Response"
msgstr "Autosvar"
msgid "Going Away"
msgstr "Tager afsted"
msgid "Coming Back"
msgstr "Kommer tilbage"
msgid "Options"
msgstr "Indstillinger"
msgid "Out of Office"
msgstr "Ikke tilstede"
msgid "Subject"
msgstr "Emne"
msgid "Body"
msgstr "Meddelelse"
msgid "Your auto response has been removed!"
msgstr "Autosvar er fjernet!"
msgid "Your auto response has been set!"
msgstr "Autosvar er aktiveret!"
msgid "You already have an auto response configured!"
msgstr "Du har allerede et autosvar indstillet!"
#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
msgid "The passwords that you supplied don't match!<br />Or are empty!"
msgstr "Adgangskoderne er ikke ens!<br />Eller er tomme!"
#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
msgid "To"
msgstr "Til"
#: postfixadmin_changepass.php:101
msgid "Unable to change your password!"
msgstr "Kan ikke ændre adgangskoden!"
#: postfixadmin_changepass.php:75
msgid "You didn't supply your current password!"
msgstr "Du glemte at skrive din nuværende adgangskode!"
#: postfixadmin_changepass.php:96
msgid "Your password has been changed!"
msgstr "Din adgangskode er ændret!"
msgid "Password current"
msgstr "Nuværende adgangskode"
msgid "Password new"
msgstr "Ny adgangskode"
msgid "Password new again"
msgstr "Ny adgangskode (igen)"
msgid "Please sign out and log back again with your new password!"
msgstr "Log af og log ind igen med din nye adgangskode!"
msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
msgstr "Jeg er ikke tilstede i perioden <dato> til <dato>. I nødstilfælde kan <kontaktperson> kontaktes."

@ -1,127 +0,0 @@
# postfixadmin - Plugin for Squirrelmail.
# Copyright (C) 2004 FLORIAN KIMMERL
# This file is distributed under the same license as the PACKAGE package.
# Florian Kimmerl <info@spacekoeln.de>, 2004.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.3-1.4\n"
"POT-Creation-Date: 2004-01-28 16:32+0100\n"
"PO-Revision-Date: 2004-01-28 16:32+0100\n"
"Last-Translator: FLORIAN KIMMERL <info@spacekoeln.de>\n"
"Language-Team: GERMAN <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-1\n"
"Content-Transfer-Encoding: 8bit\n"
#: setup.php
msgid "Forwarding"
msgstr "Weiterleitungen"
msgid "Here you can create and edit E-Mail forwards."
msgstr "Hier können Sie E-Mail-Weiterleitungen erstellen und bearbeiten."
msgid "Set an OUT OF OFFICE message or auto responder for your mail."
msgstr "Hier können Sie den Abwesenheits-Assistenten konfigurieren."
msgid "Change your mailbox password."
msgstr "Hier können Sie Passwort ändern. Nach der Änderung müssen Sie sich neu anmelden!"
#: postfixadmin_changepass.php
msgid "Alias"
msgstr "E-Mail"
msgid "Change Password"
msgstr "Passwort ändern"
msgid "Change your login password"
msgstr "Ändern Sie Ihr Zugangspasswort für POP3/IMAP"
#: postfixadmin_forward.php
msgid "Edit Alias"
msgstr "E-Mail Weiterleitungen bearbeiten"
msgid "Edit an alias* for your domain.<br />One entry per line."
msgstr "Bearbeiten Sie hier Ihre E-Mail Weiterleitungen*.<br />Ein Eintrag pro Zeile."
msgid "The email address that you have entered is not valid:"
msgstr "Die angegebene E-Mail-Adresse ist ungültig:"
msgid "Unable to locate alias!"
msgstr "Ihre Weiterleitungen können nicht angefordert werden! Versuchen Sie es später erneut."
msgid "Unable to modify the alias!"
msgstr "Ihre Weiterleitungen können nicht modifiziert werden! Versuchen Sie es später erneut."
msgid "*Additional forward-aliase always recieve messages BBC!"
msgstr "*Zusätzliche Weiterleitungen erhalten alle Nachrichten als Kopie (BCC)!"
msgid "Alias successfully changend!"
msgstr "Weiterleitungen wurden erfolgreich geändert!"
#: postfixadmin_vacation.php
msgid "Auto Response"
msgstr "Abwesenheits-Assistent"
msgid "Going Away"
msgstr "Ich bin weg"
msgid "Coming Back"
msgstr "Ich bin zurück"
msgid "Options"
msgstr "Optionen"
msgid "Out of Office"
msgstr ""
msgid "Subject"
msgstr "Betreff"
msgid "Body"
msgstr "Nachrichtentext"
msgid "Your auto response has been removed!"
msgstr "Iher Abwesenheits-Nachricht wurde deaktiviert!"
msgid "Your auto response has been set!"
msgstr "Ihre Abwesenheits-Nachricht wurde aktiviert!"
msgid "You already have an auto response configured!"
msgstr "Ihre Abwesenheits-Nachricht ist bereits aktiviert!"
msgid "back"
msgstr "zurück"
#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
msgid "The passwords that you supplied don't match!<br />Or are empty!"
msgstr "Die beiden neuen Passwörter stimmen nicht überein!<br />Oder die Felder wurden nicht ausgefüllt!"
#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
msgid "To"
msgstr "An"
#: postfixadmin_changepass.php:101
msgid "Unable to change your password!"
msgstr "Ihr Passwort kann nicht geändert werden!"
#: postfixadmin_changepass.php:75
msgid "You didn't supply your current password!"
msgstr "Ihr aktuelles Passwort wurde nicht angegeben oder ist falsch!"
#: postfixadmin_changepass.php:96
msgid "Your password has been changed!"
msgstr "Ihr Passwort wurde ergolgreich geändert!"
msgid "Password current"
msgstr "Passwort aktuell"
msgid "Password new"
msgstr "Passwort neu"
msgid "Password new again"
msgstr "Passwort neu nochmal"
msgid "Please sign out and log back again with your new password!"
msgstr "Bitte melden Sie sich hier ab und loggen sich mit Ihrem neuen Passwort erneut ein! "

@ -1,135 +0,0 @@
# postfixadmin - Plugin for Squirrelmail.
# Copyright (C) 2004 FLORIAN KIMMERL
# This file is distributed under the same license as the PACKAGE package.
# Florian Kimmerl <info@spacekoeln.de>, 2004.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: 0.3-1.4\n"
"POT-Creation-Date: 2004-01-28 16:32+0100\n"
"PO-Revision-Date: 2004-01-28 16:32+0100\n"
"Last-Translator: FLORIAN KIMMERL <info@spacekoeln.de>\n"
"Language-Team: HUNGARIAN <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ISO-8859-2\n"
"Content-Transfer-Encoding: 8bit\n"
#: setup.php
msgid "Forwarding"
msgstr "Levéltovábbítás"
msgid "Here you can create and edit E-Mail forwards."
msgstr "Itt tudod létrehozni és szerkeszteni az E-mail továbbításokat."
msgid "Set an OUT OF OFFICE message or auto responder for your mail."
msgstr "Itt lehet beállítani az automatikus válasz levél szövegét, ha az ember távol van."
msgid "Change your mailbox password."
msgstr "Itt tudod megváltoztatni a belépéshez szükséges jelszót."
#: postfixadmin_changepass.php
msgid "Alias"
msgstr "E-mail"
msgid "Change Password"
msgstr "Jelszó megváltoztatása"
msgid "Change your login password"
msgstr "Bejelentkezési jelszó megváltoztatása"
#: postfixadmin_forward.php
msgid "Edit Forward"
msgstr "Levéltovábbítás szerkesztése"
msgid "Edit Alias"
msgstr "Levéltovábbítás szerkesztése"
msgid "The email address that you have entered is not valid:"
msgstr "Az E-mail cím amit beírtál hibás:"
msgid "Unable to locate alias!"
msgstr "Hiba az e-mail címmel."
msgid "Unable to modify the alias!"
msgstr "A módosítás sikertelen!"
msgid "Alias successfully changed!"
msgstr "A módosítás sikeres!"
#: postfixadmin_vacation.php
msgid "Auto Response"
msgstr "Automatikus válasz"
msgid "Going Away"
msgstr "Házonkívül vagyok"
msgid "Coming Back"
msgstr "Visszajöttem"
msgid "Options"
msgstr "Opciók"
msgid "Out of Office"
msgstr "Házonkívül"
msgid "Subject"
msgstr "Tárgy"
msgid "Body"
msgstr "Levéltörzs"
msgid "Your auto response has been removed!"
msgstr "Az automatikus válasz törölve lett!"
msgid "Your auto response has been set!"
msgstr "Az automatikus válasz be lett állítva!"
msgid "You already have an auto response configured!"
msgstr "Már létezik egy automatikus válasz!"
#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
msgid "The passwords that you supplied don't match!<br />Or are empty!"
msgstr "A jelszavak nem egyeznek!<br />Vagy üresen hagytad a mezõket!"
#: postfixadmin_changepass.php:101
msgid "Unable to change your password!"
msgstr "A jelszó megváltoztatása sikertelen!"
#: postfixadmin_changepass.php:75
msgid "You didn't supply your current password!"
msgstr "Az aktuális jelszó nem megfelelõ!"
#: postfixadmin_changepass.php:96
msgid "Your password has been changed!"
msgstr "A jelszó változtatása sikeres volt!"
msgid "Password current"
msgstr "Aktuális jelszó"
msgid "Password new"
msgstr "Új jelszó"
msgid "Password new again"
msgstr "Új jelszó mégegyszer"
msgid "Please sign out and log back again with your new password!"
msgstr "Kérjük, jelentkezzen ki, majd újra be az új jelszavával!"
msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
msgstr "Házonkívül leszek <date> és <date> között. Sürgõs esetben értesítendõ: <contact person>."
msgid "One copy always goes to"
msgstr "Egy másolat mindig ide"
msgid "Another copy also goes to"
msgstr "További másolatok ide"
msgid "Enter an email address (or addresses) where you would like an additional copy of messages addressed to you sent.<br> Enter only one address per line."
msgstr "Sorolja fel azokat az e-mail címeket, amelyekre az Önhöz érkezõ leveleket továbbítani szeretné.<br>Soronként csak egy címet adjon meg!"
msgid "A copy of each message will go to both your mailbox and the forwarded address(es)."
msgstr "Minden Önnek címzett levél meg fog érkezni a saját postafiókjába és a továbbított e-mail címekre is."
msgid "To remove a Forward, simply delete its line from the text box."
msgstr "Ahhoz, hogy töröljön egy továbbítást, ki kell törölnie az adott sort a felsorolásból."

@ -1,129 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2004-01-29 17:35+0100\n"
"PO-Revision-Date: 2010-02-19 11:30+0100\n"
"Last-Translator: valentina <ruggiolona@tiscali.it>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: setup.php
msgid "Forwarding"
msgstr "Inoltro E-MAIL"
msgid "Here you can create and edit E-Mail forwards."
msgstr "Qui puoi creare e modificare l'inoltro dell' E-MAIL."
msgid "Set an OUT OF OFFICE message or auto responder for your mail."
msgstr "Imposta un messaggio OUT OF OFFICE / ASSENTE o un risponditore automatico per la tua mail."
msgid "Change your mailbox password."
msgstr "Modifica la tua password di accesso alla mail"
#: postfixadmin_changepass.php
msgid "Alias"
msgstr "Alias"
msgid "Change Password"
msgstr "Modifica password"
msgid "Change your login password"
msgstr "Modifica la tua password di accesso"
#: postfixadmin_forward.php
msgid "Edit Alias"
msgstr "Modifica Alias"
msgid "Edit an alias* for your domain.<br />One entry per line."
msgstr "Modifica un Alias per il tuo dominio.<br />Un record per linea."
msgid "The email address that you have entered is not valid:"
msgstr "L'indirizzo email che hai inserito non è corretto:"
msgid "Unable to locate alias!"
msgstr "Impossibile trovare l'alias!"
msgid "Unable to modify the alias!"
msgstr "Impossibile modificare l'alias!"
msgid "*Additional forward-aliase always recieve messages BBC!"
msgstr "* L'inoltro ad un alias aggiuntivo comporta l'invio del messaggio in BCC!"
msgid "Alias successfully changend!"
msgstr "Alias modificato correttamente!"
#: postfixadmin_vacation.php
msgid "Auto Response"
msgstr "Risponditore automatico"
msgid "Going Away"
msgstr "Going Away"
msgid "Coming Back"
msgstr "Coming Back"
msgid "Options"
msgstr "Opzioni"
msgid "Out of Office"
msgstr "Out of Office/Assente"
msgid "Subject"
msgstr "Oggetto"
msgid "Body"
msgstr "Messaggio"
msgid "Your auto response has been removed!"
msgstr "Il risponditore automatico è stato disattivato!"
msgid "Your auto response has been set!"
msgstr "Il risponditore automatico è stato configurato!"
msgid "You already have an auto response configured!"
msgstr "Hai gia configurato il risponditore automatico !"
#: postfixadmin_changepass.php:81
#: postfixadmin_changepass.php:87
msgid "The passwords that you supplied don't match!<br />Or are empty!"
msgstr "Le password inserite non coincidono!<br />O i campi sono vuoti!"
#: postfixadmin_forward.php:70
#: postfixadmin_forward.php:152
msgid "To"
msgstr "A"
#: postfixadmin_changepass.php:101
msgid "Unable to change your password!"
msgstr "Impossibile modificare la password"
#: postfixadmin_changepass.php:75
msgid "You didn't supply your current password!"
msgstr "Non hai indicato la password attuale!"
#: postfixadmin_changepass.php:96
msgid "Your password has been changed!"
msgstr "La tua password è stata modificata!"
msgid "Password current"
msgstr "Password attuale"
msgid "Password new"
msgstr "Nuova password"
msgid "Password new again"
msgstr "Insierisci nuovamente la nuova password"
msgid "Please sign out and log back again with your new password!"
msgstr "Per favore fai log out e riaccedi alla tua mail con la nuova password!"
msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
msgstr "Mi dispiace sarò assente dal <date> al <date>. Per richieste urgenti vi prego di contattare <nome e indirizzo email>. I will be away from <date> until <date>. For urgent matters you can contact <contact person>."

@ -1,131 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: postfixadmin-squirrelmail 2.1.0\n"
"POT-Creation-Date: 2007-11-16 17:35+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Johan <johan@double-l.nl>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-2\n"
"Content-Transfer-Encoding: 8bit\n"
#: setup.php
msgid "Forwarding"
msgstr "Doorsturen"
msgid "Here you can create and edit E-Mail forwards."
msgstr "Hier kunt u uw doorstuur adres bewerken"
msgid "Set an OUT OF OFFICE message or auto responder for your mail."
msgstr "Configureer hier uw automatisch beantwoorden"
msgid "Change your mailbox password."
msgstr "Verander uw wachtwoord"
#: postfixadmin_changepass.php
msgid "Alias"
msgstr "Alias"
msgid "Change Password"
msgstr "Verander wachtwoord"
msgid "Change your login password"
msgstr "Verander uw login wachtwoord"
#: postfixadmin_forward.php
msgid "Edit Forwards"
msgstr "Bewerk aliassen"
msgid "Edit an alias* for your email address.<br />One entry per line."
msgstr "Bewerk uw alias(sen) voor uw emailadres.<br />1 alias per regel."
msgid "The email address that you have entered is not valid:"
msgstr "Het ingevoerde adres is geen geldig adres"
msgid "Unable to locate alias!"
msgstr "Niet in staat opgeven alias te vinden!"
msgid "Unable to modify the alias!"
msgstr "Niet in staat de alias aan te passen"
msgid "*Additional forward-aliases always receive messages BBC!"
msgstr "Aliassen ontvangen altijd per BCC! "
msgid "To remove an alias, simply delete its line from the text box."
msgstr "Verwijder de regel om de alias(sen) te verwijderen."
msgid "Alias successfully changed!"
msgstr "Alias succesvol aangepast"
#: postfixadmin_vacation.php
msgid "Auto Response"
msgstr "Automatisch beantwoorden"
msgid "Going Away"
msgstr "Ik ben weg, schakel Out of Office IN"
msgid "Coming Back"
msgstr "Ik ben terug, schakel Out of Office UIT"
msgid "Options"
msgstr "Opties"
msgid "Out of Office"
msgstr "Out of office"
msgid "Subject"
msgstr "Onderwerp"
msgid "Body"
msgstr "Tekst"
msgid "Your auto response has been removed!"
msgstr "Uw automatisch beantwoorden is verwijderd!"
msgid "Your auto response has been set!"
msgstr "Uw automatisch beantwoorden is geactiveerd!"
msgid "You already have an auto response configured!"
msgstr "Automatisch beantwoorden is al geconfigureerd!"
#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
msgid "The passwords that you supplied don't match!<br />Or are empty!"
msgstr "De wachtwoorden komen niet overeen!<br />Of er is geen wachtwoord opgegeven!"
#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
msgid "To"
msgstr "Aan"
#: postfixadmin_changepass.php:101
msgid "Unable to change your password!"
msgstr "Niet in staat uw wachtwoord te wijzigen!"
#: postfixadmin_changepass.php:75
msgid "You didn't supply your current password!"
msgstr "U moet uw huidige wachtwoord opgeven!"
#: postfixadmin_changepass.php:96
msgid "Your password has been changed!"
msgstr "Uw wachtwoord is gewijzigd!"
msgid "Password current"
msgstr "Huidig wachtwoord"
msgid "Password new"
msgstr "Nieuw wachtwoord"
msgid "Password new again"
msgstr "Nieuw wachtwoord nogmaals"
msgid "Please sign out and log back again with your new password!"
msgstr "Log uit en opnieuw in met het nieuwe wachtwoord"
msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
msgstr "Ik ben niet aanwezig van <datum> tot <datum>. Voor dringende zaken kunt u contact opnemen met <Contact persoon>."

@ -1,132 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2004-01-29 17:35+0100\n"
"PO-Revision-Date: 2007-07-20 20:46+0100\n"
"Last-Translator: Krzysztof Laska <krzysiek@dip.pl>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=iso-8859-2\n"
"Content-Transfer-Encoding: 8bit\n"
#: setup.php
msgid "Forwarding"
msgstr "Przekazywanie"
msgid "Here you can create and edit E-Mail forwards."
msgstr "Tutaj mo¿esz ustawiæ i edytowaæ opcje przekazywania wiadomo¶ci"
msgid "Set an OUT OF OFFICE message or auto responder for your mail."
msgstr "Ustaw wiadomo¶æ wysy³an± nadawcom podczas Twojej nieobecno¶ci (Vacation)"
msgid "Change your mailbox password."
msgstr "Zmieñ has³o do swojego konta pocztowego"
#: postfixadmin_changepass.php
msgid "Alias"
msgstr "Konto"
msgid "Change Password"
msgstr "Zmieñ has³o"
msgid "Change your login password"
msgstr "Zmieñ has³o do swojego konta pocztowego"
#: postfixadmin_forward.php
msgid "Edit Alias"
msgstr "Edytuj adresy do przekazywania"
msgid "Edit an alias* for your domain.<br />One entry per line."
msgstr "Edytuj forward* dla swojego konta. <br/> Ka¿dy adres w nowym wierszu."
msgid "The email address that you have entered is not valid:"
msgstr "Adres e-mail jaki poda³e¶ jest niepoprawny:"
msgid "Unable to locate alias!"
msgstr "Nie mo¿na zlokalizowaæ aliasu!"
msgid "Unable to modify the alias!"
msgstr "Nie mo¿na zmodyfikowaæ aliasu!"
msgid "*Additional forward-aliase always recieve messages BBC!"
msgstr "*Wszystkie dodatkowe adresy zawsze odbieraj± wiadomo¶ci przesy³ane jako BCC! Ca³a poczta jest przekazywana i nie jest przechowywana na koncie podstawowym!"
msgid "Alias successfully changend!"
msgstr "Zmiana zachowana!"
msgid "To remove an alias, simply delete it's line from the text box."
msgstr "¯eby wy³±czyæ forward na dane konto po prostu usuñ liniê z adresem na który nie chcesz ju¿ przekazywaæ poczty."
#: postfixadmin_vacation.php
msgid "Auto Response"
msgstr "Autoodpowied¼"
msgid "Going Away"
msgstr "W³±cz autoodpowied¼"
msgid "Coming Back"
msgstr "Wy³±cz autoodpowied¼"
msgid "Options"
msgstr "Opcje"
msgid "Out of Office"
msgstr "Autoodpowied¼"
msgid "Subject"
msgstr "Temat"
msgid "Body"
msgstr "Tre¶æ"
msgid "Your auto response has been removed!"
msgstr "Twoja autoodpowied¼ zosta³a wy³±czona!"
msgid "Your auto response has been set!"
msgstr "Twoja autoodpowied¼ zosta³a w³±czona!"
msgid "You already have an auto response configured!"
msgstr "Masz ju¿ skonfigurowan± autoodpowied¼!"
#: postfixadmin_changepass.php:81
#: postfixadmin_changepass.php:87
msgid "The passwords that you supplied don't match!<br />Or are empty!"
msgstr "Has³a które poda³e¶ nie pasuj± lub s± puste!"
#: postfixadmin_forward.php:70
#: postfixadmin_forward.php:152
msgid "To"
msgstr "Do"
#: postfixadmin_changepass.php:101
msgid "Unable to change your password!"
msgstr "Nie mo¿na zmieniæ has³a!"
#: postfixadmin_changepass.php:75
msgid "You didn't supply your current password!"
msgstr "Nie poda³e¶ aktualnego has³a!"
#: postfixadmin_changepass.php:96
msgid "Your password has been changed!"
msgstr "Twoje has³o zosta³o zmienione!"
msgid "Password current"
msgstr "Bie¿±ce has³o"
msgid "Password new"
msgstr "Nowe has³o"
msgid "Password new again"
msgstr "Powtórz nowe has³o"
msgid "Please sign out and log back again with your new password!"
msgstr "Wyloguj siê i zaloguj z nowym has³em!"
msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
msgstr "Nie bêdê odbieraæ poczty pomiêdzy <data> a <data>. W sprawach pilnych proszê kontaktowaæ siê z <osoba kontaktowa>"

@ -1,127 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2004-01-29 17:35+0100\n"
"PO-Revision-Date: 2008-10-16 20:30+3\n"
"Last-Translator: Julio Covolato <julio@psi.com.br>\n"
"Language-Team: BRAZILIAN PORTUGUESE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: setup.php
msgid "Forwarding"
msgstr "Encaminhar"
msgid "Here you can create and edit E-Mail forwards."
msgstr "Aqui Voc&ecirc; pode criar e editar alias."
msgid "Set an OUT OF OFFICE message or auto responder for your mail."
msgstr "Configurar mensagem de f&eacute;rias para seu email."
msgid "Change your mailbox password."
msgstr "Troque a senha de seu email."
#: postfixadmin_changepass.php
msgid "Alias"
msgstr ""
msgid "Change Password"
msgstr "Mudar Senha"
msgid "Change your login password"
msgstr "Mude sua senha de login"
#: postfixadmin_forward.php
msgid "Edit Alias"
msgstr "Editar Alias"
msgid "Edit an alias* for your domain.<br />One entry per line."
msgstr "Editar um alias* para seu dom&iacute;nio.<br /> Uma entrada por linha."
msgid "The email address that you have entered is not valid:"
msgstr "Este endere&ccedil;o de email informado n&atilde;o &eacute; v&aacute;lido:"
msgid "Unable to locate alias!"
msgstr "Alias n&atilde;o encontrado!"
msgid "Unable to modify the alias!"
msgstr "Imposs&iacute;vel modificar o alias!"
msgid "*Additional forward-aliase always recieve messages BBC!"
msgstr "*Alias adicionais sempre recebem mensagens em BCC"
msgid "Alias successfully changend!"
msgstr "Alias alterado com sucesso!"
#: postfixadmin_vacation.php
msgid "Auto Response"
msgstr "Auto resposta"
msgid "Going Away"
msgstr "Ativar"
msgid "Coming Back"
msgstr "Desativar"
msgid "Options"
msgstr "Op&ccedil;&otilde;es"
msgid "Out of Office"
msgstr "Fora do escrit&oacute;rio"
msgid "Subject"
msgstr "Assunto"
msgid "Body"
msgstr "Mensagem"
msgid "Your auto response has been removed!"
msgstr "Sua auto resporta foi removida!"
msgid "Your auto response has been set!"
msgstr "Sua auto resposta foi ativada!"
msgid "You already have an auto response configured!"
msgstr "Voc&ecirc; ainda tem uma auto resposta ativa"
#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
msgid "The passwords that you supplied don't match!<br />Or are empty!"
msgstr "A senha digitada n&atilde;o confere!<br />Ou est&aacute; vazia"
#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
msgid "To"
msgstr "Para"
#: postfixadmin_changepass.php:101
msgid "Unable to change your password!"
msgstr "Imposs&iacute;vel alterar a sua senha!"
#: postfixadmin_changepass.php:75
msgid "You didn't supply your current password!"
msgstr "Voc&ecirc; n&atilde;o forneceu a sua senha atual!"
#: postfixadmin_changepass.php:96
msgid "Your password has been changed!"
msgstr "Sua senha foi alterada com sucesso!"
msgid "Password current"
msgstr "senha atual"
msgid "Password new"
msgstr "Nova senha"
msgid "Password new again"
msgstr "Confirme a nova senha"
msgid "Please sign out and log back again with your new password!"
msgstr "Por favor, saia e entre novamente no webmail com a nova senha"
msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
msgstr "Estarei fora do escrit&oacute;rio entre os dias <data> e <data> do m&ecirc;s de <m&ecirc;s>.<br /> Qualquer mensagem urgente, favor enviar para o email <email>."

@ -1,127 +0,0 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2004-01-29 17:35+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: setup.php
msgid "Forwarding"
msgstr ""
msgid "Here you can create and edit E-Mail forwards."
msgstr ""
msgid "Set an OUT OF OFFICE message or auto responder for your mail."
msgstr ""
msgid "Change your mailbox password."
msgstr ""
#: postfixadmin_changepass.php
msgid "Alias"
msgstr ""
msgid "Change Password"
msgstr ""
msgid "Change your login password"
msgstr ""
#: postfixadmin_forward.php
msgid "Edit Alias"
msgstr ""
msgid "Edit an alias* for your domain.<br />One entry per line."
msgstr ""
msgid "The email address that you have entered is not valid:"
msgstr ""
msgid "Unable to locate alias!"
msgstr ""
msgid "Unable to modify the alias!"
msgstr ""
msgid "*Additional forward-aliase always recieve messages BBC!"
msgstr ""
msgid "Alias successfully changend!"
msgstr ""
#: postfixadmin_vacation.php
msgid "Auto Response"
msgstr ""
msgid "Going Away"
msgstr ""
msgid "Coming Back"
msgstr ""
msgid "Options"
msgstr ""
msgid "Out of Office"
msgstr ""
msgid "Subject"
msgstr ""
msgid "Body"
msgstr ""
msgid "Your auto response has been removed!"
msgstr ""
msgid "Your auto response has been set!"
msgstr ""
msgid "You already have an auto response configured!"
msgstr ""
#: postfixadmin_changepass.php:81 postfixadmin_changepass.php:87
msgid "The passwords that you supplied don't match!<br />Or are empty!"
msgstr ""
#: postfixadmin_forward.php:70 postfixadmin_forward.php:152
msgid "To"
msgstr ""
#: postfixadmin_changepass.php:101
msgid "Unable to change your password!"
msgstr ""
#: postfixadmin_changepass.php:75
msgid "You didn't supply your current password!"
msgstr ""
#: postfixadmin_changepass.php:96
msgid "Your password has been changed!"
msgstr ""
msgid "Password current"
msgstr ""
msgid "Password new"
msgstr ""
msgid "Password new again"
msgstr ""
msgid "Please sign out and log back again with your new password!"
msgstr ""
msgid "I will be away from <date> until <date>. For urgent matters you can contact <contact person>."
msgstr ""

@ -1,125 +0,0 @@
<?php
require_once(dirname(__FILE__) . '/common.php');
$xmlrpc = get_xmlrpc();
$user = $xmlrpc->getProxy('user');
global $username;
do_header();
$USERID_USERNAME = $username;
$tmp = preg_split('/@/', $USERID_USERNAME);
$USERID_DOMAIN = $tmp[1];
$stMessage = '';
$tMessage = '';
$pPassword_admin_text = '';
$pPassword_password_current_text = '';
$pPassword_password_text = '';
$error = 0;
if ($_SERVER['REQUEST_METHOD'] == "POST") {
//$pPassword_password_text = _("pPassword_password_text");
$fPassword_current = $_POST['fPassword_current'];
$fPassword = $_POST['fPassword'];
$fPassword2 = $_POST['fPassword2'];
$username = $USERID_USERNAME;
if (!$user->login($_SESSION['username'], $_POST['fPassword_current'])) {
$error = 1;
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$pPassword_password_current_text = _("You didn't supply your current password!");
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
}
$min_length = 0;
if (isset($CONF['min_password_length'])) {
$min_length = $CONF['min_password_length'];
}
if (empty($fPassword) or ($fPassword != $fPassword2) or ($min_length > 0 && strlen($fPassword) < $min_length)) {
$error = 1;
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
if (empty($fPassword)) {
$pPassword_password_text .= _("The passwords that you supplied are empty!");
}
if ($fPassword != $fPassword2) {
$pPassword_password_text .= _("The passwords that you supplied don't match!");
}
if ($min_length > 0 && strlen($fPassword) < $min_length) {
$pPassword_password_text .= _("The password you supplied is too short!");
}
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
}
if ($error != 1) {
$success = $user->changePassword($fPassword_current, $fPassword);
if ($success) {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$tMessage = _("Your password has been changed!");
$stMessage = _("Please sign out and log back again with your new password!");
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
} else {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$tMessage = _("Unable to change your password!");
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
}
}
}
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
echo "<table bgcolor=\"$color[0]\" align=\"center\" width=\"95%\" cellpadding=\"1\" cellspacing=\"0\" border=\"0\">
<tr>
<td align=\"center\"><b>". _("Options") ." - ". _("Change Password")." </b>
<table align=\"center\" width=\"100%\" cellpadding=\"5\" cellspacing=\"0\" border=\"0\">
<tr><td bgcolor=\"$color[4]\" align=\"center\"><br>
<table align=\"center\" width=\"95%\" cellpadding=\"4\" cellspacing=\"0\" border=\"0\"><tr>
<td bgcolor=\"$color[3]\" align=\"center\"><b>" ._("Change your login password") ."\n
</b></td>
</tr>
<tr>
<td bgcolor=\"$color[0]\" align=\"center\"><form name=\"mailbox\" method=\"post\">
<b>$tMessage<b><font color=red><br>
<a href=\"../../src/signout.php\" target=\"_top\">$stMessage</a>
".$pPassword_admin_text."\n
".$pPassword_password_current_text."\n
".$pPassword_password_text."\n
</b><table width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\">
<tr>
<td width=\"37%\"><b>". _("Alias") . ":\n</td>
<td width=\"63%\">{$_SESSION['username']}</td>
</tr>
<tr>
<td><b>". _("Password current"). ":\n</td>
<td><input type=\"password\" name=\"fPassword_current\" size=\"30\" /></td>
</tr>
<tr>
<td><b>". _("Password new"). ":\n</td>
<td><input type=\"password\" name=\"fPassword\" size=\"30\" /></td>
</tr>
<tr>
<td><b>". _("Password new again"). ":\n</td>
<td><input type=\"password\" name=\"fPassword2\" size=\"30\" /></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><input type=\"submit\" name=\"submit\" value=\"" ._("Change Password") . "\" /></td>
<td>&nbsp;</td>
</tr>
</table>
<TT></TT></FORM></td>
</tr><tr><td bgcolor=\"$color[4]\" align=\"left\">&nbsp;</td>
</tr></table><BR>
</td>
</tr></table></td></tr></table>";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');

@ -1,159 +0,0 @@
<?php
require_once(dirname(__FILE__) . '/common.php');
$USERID_USERNAME = $username;
$tmp = preg_split('/@/', $USERID_USERNAME);
$USERID_LOCALPART = $tmp[0];
$USERID_DOMAIN = $tmp[1];
$xmlrpc = get_xmlrpc();
$alias = $xmlrpc->getProxy('alias');
do_header();
// Normal page request (GET)
if ($_SERVER['REQUEST_METHOD'] == "GET") {
$row = $alias->get();
if ($row === false) {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$tMessage = _("Unable to locate alias!");
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
exit(0);
}
}
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$pEdit_alias_goto = _("To");
$fGoto = $_POST['fGoto'];
// reform string into a list...
$goto = preg_replace('/\r\n/', ',', $fGoto);
$goto = preg_replace('/[\s]+/i', '', $goto);
$goto = preg_replace('/\,*$/', '', $goto);
$array = preg_split('/,/', $goto);
$error = 0;
// check that we have valid addresses in the list
foreach ($array as $key => $email_address) {
if (empty($email_address)) {
unset($array[$key]);
continue;
}
if (check_email($email_address) != "") {
$error = 1;
$tGoto = $goto;
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$tMessage = _("The email address that you have entered is not valid:") . " $email_address</font>";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
}
}
if ($error != 1) {
$flag = 'forward_and_store'; // goto = $USERID_USERNAME;
$success = $alias->update($array, $flag);
if (!$success) {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$tMessage = _("Unable to modify the alias!");
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
} else {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
echo "<p align=center><b>". _("Alias successfully changed!"). "\n</b></p>";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
echo "<p align=center><a href=\"javascript:history.go(-1)\">". _("Click here to go back") ."</a></p>";
exit;
}
}
}
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
if (!isset($tMessage)) {
$tMessage = '';
}
echo "<table bgcolor=\"$color[0]\" align=\"center\" width=\"95%\" cellpadding=\"1\" cellspacing=\"0\" border=\"0\">
<tr>
<td align=\"center\" bgcolor=\"$color[0]\" colspan=\"2\">
<b>". _("Options") ." - ". _("Edit Alias"). " </b>
<table align=\"center\" width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">
<tr>
<td bgcolor=\"$color[4]\" align=\"center\">
<table align=\"center\" width=\"100%\">
<tr>
<td align=\"left\">". _("Edit an alias* for your email address.<br />One entry per line."). " </td>
</tr>
<tr>
<td align=\"left\">". _("*Additional forward-aliases always receive messages BCC!"). "\n
</tr>
<tr>
<td align=\"left\">" . _("To remove an alias, simply delete its line from the text box.") . "</td>
</tr>
</table>
<table align=\"center\" width\"95%\" cellpadding=\"5\" cellspacing=\"1\">
<form name=\"mailbox\" method=\"post\">
<tr>
<td bgcolor=\"$color[3]\" align=\"center\"><b>". _("Edit Forwards"). "</b>
</td>
</tr>
<tr>
<td bgcolor=\"$color[5]\" align=\"center\">$tMessage
<table cellpadding=\"5\" cellspacing=\"1\">
<tr>
<th align=\"left\">". _("Alias"). ":\n
</th>
<td align=\"left\">" . $_SESSION['username'] . "</td>
</tr>
<tr>
<th>&nbsp;</th>
<td>&nbsp;</td>
</tr>
<tr>
<th align=\"left\" valign=\"top\">". _("To"). ":\n</th>
<td>
<textarea rows=\"8\" cols=\"50\" name=\"fGoto\">";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
$aliases = $alias->get();
foreach ($aliases as $address) {
if ($address == "" || $address == null) {
continue;
}
print "$address\n";
}
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
echo "
</textarea>
</td>
</tr>
<tr>
<th>&nbsp;</th>
<td>&nbsp;</td>
</tr>
<tr>
<th>&nbsp;</th>
<td align=\"left\"colspan=\"2\">
<input type=\"submit\" name=\"submit\" value=\"" . _("Edit Alias") . "\">
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
</td>
</tr>
</table>
</td></tr>
</table>
";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');

@ -1,141 +0,0 @@
<?php
require_once(dirname(__FILE__) . '/common.php');
$xmlrpc = get_xmlrpc();
$vacation = $xmlrpc->getProxy('vacation');
$VACCONFTXT = _("I will be away from <date> until <date>. For urgent matters you can contact <contact person>.");
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
$VACCONF = <<<EOM
$VACCONFTXT
EOM;
do_header();
$USERID_USERNAME = $username;
$tmp = preg_split('/@/', $USERID_USERNAME);
$USERID_DOMAIN = $tmp[1];
if ($_SERVER['REQUEST_METHOD'] == "GET") {
$details = $vacation->getDetails();
if ($vacation->checkVacation()) {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$tMessage = _("You already have an auto response configured!");
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
echo "<table bgcolor=\"#b8cbdc\" align=\"center\" width=\"95%\" cellpadding=\"1\" cellspacing=\"0\" border=\"0\"><tr>
<td align=\"center\"><b>". _("Options") ." - ". _("Auto Response") ."</b>
<table align=\"center\" width=\"100%\" cellpadding=\"5\" cellspacing=\"0\" border=\"0\">
<tr><td bgcolor=\"$color[4]\" align=\"center\"><br>
<table align=\"center\" width=\"70%\" cellpadding=\"4\" cellspacing=\"0\" border=\"0\"><tr>
<td bgcolor=\"$color[3]\" align=\"center\"><b>". _("Auto Response") ."\n
</b></td></tr><tr>
<td bgcolor=\"$color[0]\" align=\"center\"><form name=\"vacation\" method=\"post\">
<table width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\">
<tr>
<td><center>$tMessage<p></center></td>
</tr>
<tr>
<td> <div align=\"center\">
<input type=\"submit\" name=\"fBack\" value=\"" . _("Coming Back"). "\" />
</div></td>
</tr>
</table>
<TT></TT></FORM>
</td>
</tr><tr><td bgcolor=\"$color[4]\" align=\"left\">&nbsp;</td>
</tr></table><BR></td></tr></table></td></tr></table>";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
} else {
$tSubject = "Out of Office";
$tSubject = $details['subject'];
$VACCONF = $details['body'];
$tMessage = '';
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
echo "<table bgcolor=\"$color[0]\" align=\"center\" width=\"95%\" cellpadding=\"1\" cellspacing=\"0\" border=\"0\">
<tr>
<td align=\"center\"><b>". _("Options") ." - ". _("Auto Response") ." </b>
<table align=\"center\" width=\"100%\" cellpadding=\"5\" cellspacing=\"0\" border=\"0\">
<tr><td bgcolor=\"$color[4]\" align=\"center\"><br>
<table align=\"center\" width=\"70%\" cellpadding=\"4\" cellspacing=\"0\" border=\"0\"><tr>
<td bgcolor=\"$color[3]\" align=\"center\"><b>" . _("Auto Response") ."\n
</b></td></tr><tr>
<td bgcolor=\"$color[0]\" align=\"center\"><form name=\"vacation\" method=\"post\">$tMessage
<table width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"2\"><tr>
<td width=\"23%\">". _("Subject") .":\n</td>
<td width=\"2%\">&nbsp;</td>
<td width=\"69%\"><input type=\"text\" name=\"fSubject\" value=\"" . $tSubject . "\" /></td>
<td width=\"2%\">&nbsp;</td>
<td width=\"4%\">&nbsp;</td>
</tr><tr>
<td>". _("Body") .":\n</td>
<td>&nbsp;</td>
<td><textarea rows=\"10\" cols=\"80\" name=\"fBody\">$VACCONF\n
</textarea></td><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td>
<td><input type=\"submit\" name=\"fAway\" value=\"" . _("Going Away") . "\" /></td>
<td>&nbsp;</td><td>&nbsp;</td></tr>
</table><TT></TT></FORM></td>
</tr><tr><td bgcolor=\"$color[4]\" align=\"left\">&nbsp;</td>
</tr></table><BR></td></tr></table></td></tr></table>";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
}
}
if ($_SERVER['REQUEST_METHOD'] == "POST") {
$fBack = null;
$fAway = null;
foreach (array('fBack', 'fAway', 'fSubject', 'fBody') as $key) {
$$key = null;
if (isset($_POST[$key])) {
$$key = $_POST[$key];
}
}
if (!empty($fBack)) {
$success = $vacation->remove();
if (!$success) {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$tMessage = _("Unable to update your auto response settings!");
echo "<p>This may signify an error; please contact support (1)</p>";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
} else {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
echo "<p align=center><b>". _("Your auto response has been removed!") ."</b></p>";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
}
}
if (!empty($fAway)) {
// add record into vacation
$success = $vacation->setAway($fSubject, $fBody);
if (!$success) {
$error = 1;
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$tMessage = _("Unable to update your auto response settings!");
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
} else {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
echo "<p align=center><b>". _("Your auto response has been set!") ."</b></p>";
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
}
}
}

@ -1,62 +0,0 @@
<?php
// vim:ts=4:sw=4:et
if (!defined('SM_PATH')) {
die("Invalid internal state (don't access file directly)");
}
include_once(SM_PATH . 'functions/i18n.php');
function squirrelmail_plugin_init_postfixadmin() {
include(dirname(__FILE__) . '/config.php');
global $squirrelmail_plugin_hooks;
$squirrelmail_plugin_hooks['optpage_register_block']['postfixadmin'] = 'postfixadmin_optpage_register_block';
}
function postfixadmin_version() {
return '2.3.0';
}
function postfixadmin_optpage_register_block() {
// Gets added to the user's OPTIONS page.
global $optpage_blocks;
global $AllowVacation;
global $AllowChangePass;
// if ( !soupNazi() ) {
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
$optpage_blocks[] = array(
'name' => _("Forwarding"),
'url' => '../plugins/postfixadmin/postfixadmin_forward.php',
'desc' => _("Here you can create and edit E-Mail forwards."),
'js' => false
);
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
if ($AllowVacation) {
$optpage_blocks[] = array(
'name' => _("Auto Response"),
'url' => '../plugins/postfixadmin/postfixadmin_vacation.php',
'desc' => _("Set an OUT OF OFFICE message or auto responder for your mail."),
'js' => false
);
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
}
bindtextdomain('postfixadmin', SM_PATH . 'plugins/postfixadmin/locale');
textdomain('postfixadmin');
if ($AllowChangePass) {
$optpage_blocks[] = array(
'name' => _("Change Password"),
'url' => '../plugins/postfixadmin/postfixadmin_changepass.php',
'desc' => _("Change your mailbox password."),
'js' => false
);
bindtextdomain('squirrelmail', SM_PATH . 'locale');
textdomain('squirrelmail');
}
}

@ -1,193 +0,0 @@
<?php
/*
Virtual Mail Delete
by George Vieira <george at citadelcomputer dot com dot au>
You can run this from your crontab with something like
0 4 * * * * vmail php -q virtualmaildel.php >/dev/null
Changes:
2017.08.31 updated to use PHP mysqli extension.
2018.02.23 removing Sieve filters if exists.
Tadas Ustinavičius <tadas at ring dot lt> ( https://github.com/postfixadmin/postfixadmin/pull/70 )
*/
$CONF = [];
// Either, uncomment this (and change to work)
//require_once('/path/to/postfixadmin/config.inc.php');
// OR uncomment this.
/*
$CONF = [
'database_host' => 'localhost',
'database_user' => 'someone',
'database_password' => 'something',
'database_name' => 'mydb'
];
*/
$MAKE_CHANGES = false; // change to true when you're happy this isn't going to trash your server.
if (empty($CONF)) {
die("\nPlease configure me\n\n");
}
// Where's the homedir accounts stored. (GET THIS RIGHT OTHERWISE IT THINK NONE EXIST AND DELETES ALL)
$homedir = '/home/virtual';
if (! is_dir($homedir)) {
die("Cannot find home directory for virtual mailboxes in $homedir\n");
}
//
// Recursive Delete Function
//
function deldir($dir) {
$current_dir = opendir($dir);
while ($entryname = readdir($current_dir)) {
if (is_dir("$dir/$entryname") and ($entryname != "." and $entryname!="..")) {
deldir("{$dir}/{$entryname}");
} elseif ($entryname != "." and $entryname!="..") {
unlink("{$dir}/{$entryname}");
}
}
closedir($current_dir);
@rmdir($dir);
}
// --- Main Start ---
$dir = [];
//
// Get list of directories
//
$fr = opendir($homedir);
// TODO: Would glob($homedir . '/**/*/new') be somewhat quicker/shorter/less effort?
while (($domain = readdir($fr)) !== false) {
//
// Check if it's a dir
//
if ($domain == "." || $domain == ".." || filetype($homedir .'/'. $domain) != "dir") {
continue;
}
//
// Open the (assumed) DOMAIN directory
//
$ff = opendir($homedir .'/'. $domain);
while (($user = readdir($ff)) !== false) {
//
// Check for directories assuming it's a user account
//
if ($user == "." || $user == ".." || filetype($homedir .'/'. $domain .'/'. $user) != "dir") {
continue;
}
//
// if the dir 'new' exists inside then it's an account
//
if (file_exists($homedir .'/'. $domain .'/'. $user .'/'. "new")) {
$dir[$domain][$user] = "";
} else {
//
// Alert that the dir doesn't have a 'new' dir, possibly not an account. Leave it.
//
echo "UNKNOWN : " . $homedir ."/". $domain ."/". $user ."/new NOT FOUND. Possibly not an account. Leaving untouched\n";
}
}
}
//
// OK, got an array of accounts from the dir, Now connect to the DB and check them
//
$conx = mysqli_connect($CONF['database_host'], $CONF['database_user'], $CONF['database_password'], $CONF['database_name']);
//
// Is there a problem connecting?
//
if (! $conx || mysqli_connect_errno()) {
echo "DB connection failed." . mysqli_connect_error() . "\n";
die("Problem connecting to the database. ");
}
//
// Select all mailboxes to verify against dirs listed in array
//
$query = "SELECT * FROM mailbox";
$result = mysqli_query($conx, $query);
//
// Query the mailbox table
//
if (! $result) {
die("Failed to query mailbox table.");
}
//
// Fetch the list of results
//
while ($row = mysqli_fetch_assoc($result)) {
//
// Pull apart the maildir field, needed to figure out the directory structure to compare
//
$strip = explode("/", $row['maildir']);
//
// Unset the array if it exists. This stops it being erased later.
//
unset($dir[ $strip[0] ][ $strip[1] ]);
}
//
// If there are results. unset the domain too.
//
if (count($dir[$strip[0]])==0 and mysqli_num_rows($result)>0) {
unset($dir[$strip[0]]);
}
//
// OK, time to clean up. All known users/domains have been removed from the list.
//
//
// If the array still exists (incase nothing there)
//
if (is_array($dir)) {
//
// Go through each dir
//
foreach ($dir as $key => $value) {
//
// Is this a user array?
//
if (!is_array($value)) {
continue;
}
//
// Go through and nuke the folders
//
foreach ($value as $user => $value2) {
// Nuke.. need any more explanations?
$path = $homedir . '/' . $key . '/' . $user;
$sieve_path = $homedir . '/.sieve/' . $key . '/' . $user;
$sieve_exists = file_exists($sieve_path);
// check if user has Sieve filters created
if ($MAKE_CHANGES) {
deldir($path);
if ($sieve_exists) {
deldir($sieve_path);
}
} else {
echo " - Would recursively delete : $path \n";
if ($sieve_exists) {
echo " - Would recursively delete Sieve filters : $sieve_path \n";
}
}
}
}
}
echo "Cleanup process completed\n";

File diff suppressed because it is too large Load Diff

@ -1,39 +0,0 @@
#
# Postfix Admin
# by Mischa Peters <mischa at high5 dot net>
# Copyright (c) 2002 - 2005 High5!
# Licensed under GPL for more info check GPL-LICENSE.TXT
#
Please follow these steps if your mailserver is used as a backup MX for some
(or all) of your domains.
Note: The setup described in this file only checks the domain, not the full
mail address.
You should use "reject_unverified_recipient" in your postfix config or setup
"relay_recipient_maps" with a list of valid mail adresses on the primary mx
to avoid that your backup MX accepts mails for non-existing recipient adresses.
Without this, your backup MX might become a backscatter source.
1. Modify main.cf
-----------------
In order for Postfix to use MySQL for relay_domains add the following
to your main.cf
relay_domains = proxy:mysql:/usr/local/etc/postfix/mysql_relay_domains_maps.cf
2. mysql_relay_domains_maps.cf
------------------------------
You will need to put this into a text file for postfix to pickup.
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain = '%s' AND backupmx = '1'
3. Restart Postfix
-------------------
When you are done make sure to restart Postfix so the changes take effect.

@ -1,228 +0,0 @@
#
# Dovecot configuration for Postfix Admin
# Originally written by: Massimo <AndyCapp> Danieli
# Revised by: Sampsa Hario <shario> for Dovecot v1.0
# Revised by: David Goodwin <david@palepurple.co.uk> for Dovecot 2.1.x (2014/01/02)
#
More complete Dovecot documentation:
http://wiki.dovecot.org/Quota
http://wiki.dovecot.org/Quota/Dict
http://www.opensourcehowto.org/how-to/mysql/mysql-users-postfixadmin-postfix-dovecot--squirrelmail-with-userprefs-stored-in-mysql.html
Here are the relevant parts of Dovecot v2.1.x configuration for Postfixadmin setup.
Please refer to Dovecot documentation for complete information.
The setup gets userdb and passdb info from MySQL as well as quotas, and
uses dict backend to store used quotas as key=value pairs so that they can
be viewed real-time in Postfixadmin.
1. Dovecot setup
-----------------
A basic /etc/dovecot/dovecot.conf is as follows, this was generated using 'dovecot -n' on a vanilla install and then
changing to talk to a PostgreSQL or MySQL database.
# BEGIN /etc/dovecot/dovecot.conf:
# Change this to where your mail root is, this needs to match whatever structure postfix expects....
# See also: https://wiki.dovecot.org/MailLocation - %d domain, %u full username, %n user part (%u with no domain)
mail_location = maildir:/var/mail/vmail/%u/
namespace inbox {
inbox = yes
location =
mailbox Drafts {
special_use = \Drafts
}
mailbox Junk {
special_use = \Junk
}
mailbox Sent {
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
mailbox Trash {
special_use = \Trash
}
prefix =
}
protocols = "imap pop3"
# change to 'no' if you don't have ssl cert/keys, and comment out ssl_cert/ssl_key
ssl = yes
ssl_cert = </etc/dovecot/private/dovecot.pem
ssl_key = </etc/dovecot/private/dovecot.pem
# login is for outlook express smtpd auth
auth_mechanisms = plain login
# If you're having trouble, try uncommenting these:
#auth_debug = yes
#auth_debug_passwords = yes
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf
}
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf
}
# Uncomment this if you want Postfix to be able to do smtpd auth through dovecot
# At a minimum Postfix probably needs smtpd_sasl_type = dovecot
# And additionally: smtpd_sasl_path = private/auth
#service auth {
# unix_listener /var/spool/postfix/private/auth {
# mode = 0660
# user = postfix
# group = postfix
# }
#}
# Needs to match Postfix virtual_uid_maps
first_valid_uid = 1001
# allow plaintext auth (change to 'yes' to block plaintext passwords)
disable_plaintext_auth = no
#END
2. Dovecot *sql setup
----------------------
Below you'll find the relevant part of dovecot-sql.conf file regarding our
setup.
Things you will probably need to change are db connection settings (connect=)
and the default_pass_scheme.
#BEGIN /etc/dovecot/dovecot-sql.conf
connect = host=localhost dbname=postfix user=postfix password=postfix
# Use either
driver = mysql
# Or
# driver = pgsql
# Default password scheme - change to match your Postfixadmin setting.
# depends on your $CONF['encrypt'] setting:
# md5crypt -> MD5-CRYPT
# md5 -> PLAIN-MD5
# cleartext -> PLAIN
default_pass_scheme = MD5-CRYPT
# Query to retrieve password. user can be used to retrieve username in other
# formats also.
password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'
# Query to retrieve user information, note uid matches dovecot.conf AND Postfix virtual_uid_maps parameter.
# MYSQL:
user_query = SELECT CONCAT('/var/mail/vmail/', maildir) AS home, 1001 AS uid, 1001 AS gid,
CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active='1'
# PostgreSQL:
# user_query = SELECT '/var/mail/vmail/' || maildir AS home, 1001 AS uid, 1001 AS gid,
# '*:bytes=' || quota AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
#END /etc/dovecot/dovecot-sql.conf
3. Dovecot v1.0 quota support (optional)
----------------------------------------
Please note that you need to use Dovecot's own local delivery agent to
enforce and update quotas. Then you can view real-time used quotas in
Postfixadmin.
Add to dovecot.conf:
## IMAP quota
protocol imap {
mail_plugins = quota
}
## POP quota
protocol pop3 {
mail_plugins = quota
}
## Local Delivery Agent
protocol lda {
mail_plugins = quota
}
## Dictionary DB proxy
dict {
quota = mysql:/etc/dovecot-dict-quota.conf
}
## Default quota values
plugin {
quota = dict:storage=200000 proxy::quota
}
Change dovecot-sql.conf to return quota values:
for MySQL:
user_query = SELECT maildir, 1001 AS uid, 1001 AS gid, CONCAT('dict:storage=',floor(quota/1000),' ::proxy::quota') as quota FROM mailbox WHERE username = '%u' AND active='1'
for PostgreSQL:
user_query = SELECT maildir, 1001 AS uid, 1001 AS gid, 'dict:storage=' || floor(quota/1000) || '::proxy::quota' as quota FROM mailbox WHERE username = '%u' AND active='1'
Create file dovecot-dict-quota.conf.
For dovecot 1.0 & 1.1, use this as a template:
driver = mysql
connect = host=localhost dbname=postfix user=postfix password=postfix
default_pass_scheme = MD5-CRYPT
table = quota
select_field = current
where_field = path
username_field = username
If you use dovecot 1.2 or newer, use this:
connect = host=localhost dbname=postfix user=postfix password=postfix
map {
pattern = priv/quota/storage
table = quota2
username_field = username
value_field = bytes
}
map {
pattern = priv/quota/messages
table = quota2
username_field = username
value_field = messages
}
Create database in Mysql:
(This is automatically done by postfixadmin's setup.php)
Enable quota support in Postfixadmin config.inc.php:
$CONF['used_quotas'] = 'YES';
$CONF['quota'] = 'YES';
Note: The above text describes the configuration for dovecot 1.0 & 1.1 quota table format.
If you use dovecot 1.2 or newer,
- use the 'quota2' table (also created by setup.php)
- set $CONF['new_quota_table'] = 'YES'

@ -1,36 +0,0 @@
Frequently Asked Questions:
1) Why isn't PostfixAdmin creating my mailbox?
- PostfixAdmin is only a web interface for storing configuration settings.
It does not (by default!) have the ability to create mail folders on disk.
In a normal setup, sending the 'Welcome' email accomplishes this task -
as Courier/Cyrus/etc do it (and have permission to do so)
2) I've deleted the mailbox from PostfixAdmin, yet it still exists on disk? Why?
- This is related to #1 above - namely, PostfixAdmin (which is a php web
application) does not have permission to modify the mailbox files on disk.
You need to either manually remove the directories
(e.g. rm -Rf /var/spool/mail/vmail/something@example.org)
or install the postfixadmin-mailbox-postdeletion.sh script (See ADDITIONS/)
and modify config.inc.php appropriately.
3) How do I have to setup sudo to run the $CONF['*_script'] scripts?
- run visudo to edit the sudo configuration file
- add a line like this for every script you want to run:
wwwrun ALL = (courier) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postcreation.sh
(replace usernames and path according to your setup)
4) I try and create a mailbox, but it keeps saying "Invalid email address"... ?
- Postfixadmin, by default, attempts to verify an email address is valid, partly by
checking that the domain exists. For most people this works as expected, but
if it doesn't for you, try editing $CONF['emailcheck_resolve_domain'] to 'NO' in
config.inc.php and try again.

@ -1,50 +0,0 @@
Horde integration with Postfixadmin
This is taken from the following thread :
https://sourceforge.net/forum/forum.php?thread_id=1869141&forum_id=676076
Namely :
"Hi, people, I was wondering if anyone was using PA with Horde3. I want my users to be able to change teir password from inside Horde, so I was wondering if anyone has implemented a custom hook or defined a SQL query to make the password change possible. "
Solution :
"Hi,
that works for me without any hook - with the SQL driver. I connect through IP to localhost. You can also try socket connection...
my horde/passwd/config/backends.php looks like:
$backends['sql'] = array (
'name' => 'Mail SQL Server',
'preferred' => '',
'password policy' => array(
'minLength' => 3,
'maxLength' => 8,
'maxSpace' => 0,
'minUpper' => 1,
'minLower' => 1,
'minNumeric' => 1,
'minSymbols' => 1
),
'driver' => 'sql',
'params' => array(
'phptype' => 'mysql',
'hostspec' => '127.0.0.1',
'port' => '3306',
'protocol' => 'tcp',
'username' => 'postfix',
'password' => 'yourpostfixdbpassword',
'encryption' => 'crypt-md5',
'database' => 'postfix',
'table' => 'mailbox',
'user_col' => 'username',
'pass_col' => 'password',
'show_encryption' => false
)
); "
Thanks to 'Kope' for the solution, and of course Luis Hernán Otegui (slimshady76) for asking the question.

@ -1,17 +0,0 @@
#
# Postfix Admin
# by Mischa Peters <mischa at high5 dot net>
# Copyright (c) 2002 - 2005 High5!
# Licensed under GPL for more info check GPL-LICENSE.TXT
#
If you want to contribute a translation, please follow these easy steps:
- download your language file from SVN
http://postfixadmin.svn.sourceforge.net/viewvc/postfixadmin/trunk/languages/
- search for lines with '# XXX' comments and
- translate the line
- remove the '# XXX'
Note: The file is utf-8 encoded. You can also use htmlentities.
- post your translation to the Sourceforge tracker
http://sourceforge.net/tracker/?group_id=191583&atid=937966

@ -1,26 +0,0 @@
---------------------------------------
The different parts of PostfixAdmin
Postfix Admin has a concept of a "global" administrator (think 'root') and
domain administrators. When you install PostfixAdmin, the setup.php file
will ask you to create the global administrators account. Using this global
account, you can (if you so wish) create domain administrators who are
limited to making changes within the domains you specify for them.
Historically when you logged in as the 'global' (or superadmin) user, you'd
access /admin; with version 2.2.0, this 'functionality' was removed (as there
was excessive code duplication) and everyone uses the same login.php script.
Needless to say, as a global administrator, you can do all kinds of bad things -
like deleting domains and stopping delivery of mail to a particular mailbox. So
- take care, and if you're unsure take semi-regular backups.
If you login, and you are not an administrator (i.e. you are a 'regular' user
who just has a mailbox on the server), then you will only see functionality to
modify your own account - e.g. change password, edit forward records and specify
whether you are on vacation (out of office) or not.

@ -1,192 +0,0 @@
#!/bin/bash
content="
Postfix configuration for use with PostfixAdmin
-----------------------
Your installation of Postfix MUST support either MySQL or Postgres
lookup tables. You can verify that with 'postconf -m'
Its generally recommended to use proxy as well (which should also appear in
postconf -m) Three main.cf variables are involved:
virtual_mailbox_domains = proxy:mysql:/etc/postfix/sql/mysql_virtual_domains_maps.cf
virtual_alias_maps =
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_maps.cf,
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_maps.cf,
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_catchall_maps.cf
virtual_mailbox_maps =
proxy:mysql:/etc/postfix/sql/mysql_virtual_mailbox_maps.cf,
proxy:mysql:/etc/postfix/sql/mysql_virtual_alias_domain_mailbox_maps.cf
# For transport map support, also use the following configuration:
relay_domains = proxy:mysql:/etc/postfix/sql/mysql_relay_domains.cf
transport_maps = proxy:mysql:/etc/postfix/sql/mysql_transport_maps.cf
# Also set the config.inc.php setting transport=YES
# and add the transport choices to transport_options.
# if you let postfix store your mails directly (without using maildrop, dovecot deliver etc.)
virtual_mailbox_base = /var/mail/vmail
# or whereever you want to store the mails
Where you chose to store the .cf files doesn't really matter, but they will
have database passwords stored in plain text so they should be readable only
by user postfix, or in a directory only accessible to user postfix.
This isn't necessarily all you need to do to Postfix to get up and
running. Also, additional changes are needed for the vacation
autoreply features.
-------------------------
Contents of the files
These are examples only, you will likely have to and want to make some
customizations. You will also want to consider the config.inc.php
settings for domain_path and domain_in_mailbox. These examples
use values of domain_path=YES and domain_in_mailbox=NO
You can create these files (with your values for user, password, hosts and
dbname) automatically by executing this file (sh POSTFIX_CONF.txt).
Please note that the generated files are for use with MySQL.
If you are using PostgreSQL, you'll need to do some changes to the queries:
- PostgreSQL uses a different implementation for boolean values, which means
you'll need to change active='1' to active='t' in all queries
- PostgreSQL does not have a concat() function, instead use e.g.
.... alias.address = '%u' || '@' || alias_domain.target_domain AND ....
mysql_virtual_alias_maps.cf:
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = '1'
#expansion_limit = 100
mysql_virtual_alias_domain_maps.cf:
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('%u', '@', alias_domain.target_domain) AND alias.active='1' AND alias_domain.active='1'
mysql_virtual_alias_domain_catchall_maps.cf:
# handles catch-all settings of target-domain
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias,alias_domain WHERE alias_domain.alias_domain = '%d' and alias.address = CONCAT('@', alias_domain.target_domain) AND alias.active='1' AND alias_domain.active='1'
(See above note re Concat + PostgreSQL)
mysql_virtual_domains_maps.cf:
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1'
#query = SELECT domain FROM domain WHERE domain='%s'
#optional query to use when relaying for backup MX
#query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'
#optional query to use for transport map support
#query = SELECT domain FROM domain WHERE domain='%s' AND active = '1' AND NOT (transport LIKE 'smtp%%' OR transport LIKE 'relay%%')
#expansion_limit = 100
mysql_virtual_mailbox_maps.cf:
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = '1'
#expansion_limit = 100
mysql_virtual_alias_domain_mailbox_maps.cf:
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox,alias_domain WHERE alias_domain.alias_domain = '%d' and mailbox.username = CONCAT('%u', '@', alias_domain.target_domain) AND mailbox.active='1' AND alias_domain.active='1'
mysql_relay_domains.cf:
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' AND active = '1' AND (transport LIKE 'smtp%%' OR transport LIKE 'relay%%')
mysql_transport_maps.cf:
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT transport FROM domain WHERE domain='%s' AND active = '1'
(See above note re Concat + PostgreSQL)
# For quota support
mysql_virtual_mailbox_limit_maps.cf:
user = postfix
password = password
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE username='%s' AND active = '1'
-------------------------
More information - HowTo docs that use PostfixAdmin
http://postfix.wiki.xs4all.nl/index.php?title=Virtual_Users_and_Domains_with_Courier-IMAP_and_MySQL
http://wiki.dovecot.org/HowTo/DovecotLDAPostfixAdminMySQL
" # end content
# generate config files out of this file
# to do this, run sh POSTFIX_CONF.txt
POSTFIX_CONF="$0"
map_files="`sed -n '/^mysql.*cf:/ s/://p' < \"$0\"`"
tmpdir="`mktemp -d /tmp/postfixadmin-XXXXXX`" || { echo "Error: could not create tempdir" >&2 ; exit 1; }
echo $tmpdir
echo 'Database host? (often localhost)'
read hosts
test -z "$hosts" && hosts=localhost
echo 'Database name?'
read dbname
test -z "$dbname" && { echo "Error: you did not enter a database name" >&2 ; exit 1; }
echo Database user?
read user
test -z "$user" && { echo "Error: you did not enter a database username" >&2 ; exit 1; }
echo Database password?
read password
test -z "$password" && { echo "Error: you did not enter a database password" >&2 ; exit 1; }
for file in $map_files ; do
(
echo "# $file"
sed -n "/$file:/,/^$/ p" < "$POSTFIX_CONF" | sed "
1d ; # filename
s/^user =.*/user = $user/ ;
s/^password =.*/password = $password/ ;
s/^hosts =.*/hosts = $hosts/ ;
s/^dbname =.*/dbname = $dbname/ ;
"
) > "$tmpdir/$file"
done
echo "Config files have been written to $tmpdir. Please check their content and move them to /etc/postfix/sql/."
echo "Do not forget to edit /etc/postfix/main.cf as described in $POSTFIX_CONF."

@ -1,221 +0,0 @@
# Example configuration
The below covers some default(ish) configuration things for using Postfix, Dovecot with PostgreSQL.
# Postfix
Assumptions :
* Mail is delivered into /var/mail/vmail/foo@example.com/
* The user with id 8 is used for ownership of mail files.
* PostgreSQL is running on the local server
* Dovecot is running on the local server, and SASL is used to allow authenticated clients to mail out.
## /etc/postfix/main.cf
The proxy: bits are optional, you may need to install an additional postfix package on your server to enable them.
i.e. proxy:pgsql:/path/to/file is equivalent to pgsql:/path/to/file. Use of 'proxy:' may lead to a small performance boost.
```
relay_domains = $mydestination, proxy:pgsql:/etc/postfix/pgsql/relay_domains.cf
virtual_alias_maps = proxy:pgsql:/etc/postfix/pgsql/virtual_alias_maps.cf
virtual_mailbox_domains = proxy:pgsql:/etc/postfix/pgsql/virtual_domains_maps.cf
virtual_mailbox_maps = proxy:pgsql:/etc/postfix/pgsql/virtual_mailbox_maps.cf
virtual_mailbox_base = /var/mail/vmail
virtual_mailbox_limit = 512000000
virtual_minimum_uid = 8
virtual_transport = virtual
virtual_uid_maps = static:8
virtual_gid_maps = static:8
local_transport = virtual
local_recipient_maps = $virtual_mailbox_maps
```
and for Postfix SASL support :
```
# SASL Auth for SMTP relaying
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_authenticated_header = yes
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
broken_sasl_auth_clients = yes
```
## /etc/postfix/pgsql/relay_domains.cf
```
user = postfix
password = whatever
hosts = localhost
dbname = postfix
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = true
```
## /etc/postfix/pgsql/virtual_alias_maps.cf
```
user = postfix
password = whatever
hosts = localhost
dbname = postfix
query = SELECT goto FROM alias WHERE address='%s' AND active = true
```
## /etc/postfix/pgsql/virtual_domains_maps.cf
```
user = postfix
password = whatever
hosts = localhost
dbname = postfix
#query = SELECT domain FROM domain WHERE domain='%s'
#optional query to use when relaying for backup MX
query = SELECT domain FROM domain WHERE domain='%s' and backupmx = false and active = true
```
## /etc/postfix/pgsql/virtual_mailbox_limits.cf
```
# Used for quota
user = postfix
password = whatever
hosts = localhost
dbname = postfix
query = SELECT quota FROM mailbox WHERE username='%s'
```
## /etc/postfix/pgsql/virtual_mailbox_maps.cf
```
user = postfix
password = whatever
hosts = localhost
dbname = postfix
query = SELECT maildir FROM mailbox WHERE username='%s' AND active = true
```
# Dovecot
(This is from version 2.2.27, Debian Stretch)
## /etc/dovecot/dovecot.conf
```
mail_location = maildir:/var/mail/vmail/%u/
namespace inbox {
type = private
inbox = yes
location =
mailbox Drafts {
special_use = \Drafts
}
mailbox Junk {
special_use = \Junk
}
mailbox Sent {
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
mailbox Trash {
special_use = \Trash
}
prefix =
}
protocols = "imap pop3"
# Requires certificates ...
#ssl = yes
#ssl_cert = </etc/dovecot/private/something.pem
#ssl_key = </etc/letsencrypt/certs/something.key
login_greeting = My Mail Server
# http://wiki2.dovecot.org/Authentication/Mechanisms
# login is for outlook express ...
auth_mechanisms = plain login
#auth_debug = yes
#auth_debug_passwords=yes
# Postfix - Sasl auth support.
service auth {
# Postfix smtp-auth
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
# Auth process is run as this user.
user = postfix
group = postfix
}
service imap {
executable = imap
}
userdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf
}
passdb {
driver = sql
args = /etc/dovecot/dovecot-sql.conf
}
# Needs to match Postfix virtual_uid_maps
first_valid_uid = 8
# disallow or allow plaintext auth.
disable_plaintext_auth = yes
mail_plugins = $mail_plugins zlib
plugin {
zlib_save_level = 6
zlib_save = gz
}
protocol imap {
mail_plugins = $mail_plugins imap_zlib
}
mail_max_userip_connections = 50
log_path = /var/log/dovecot.log
```
## /etc/dovecot/dovecot-sql.conf
Ideally dovecot has a different read only database user.
```
connect = host=localhost dbname=postfix user=dovecot password=whatever
driver = pgsql
# Default password scheme - change to match your Postfixadmin setting.
# depends on your $CONF['encrypt'] setting:
# md5crypt -> MD5-CRYPT
# md5 -> PLAIN-MD5
# cleartext -> PLAIN
default_pass_scheme = MD5-CRYPT
# Query to retrieve password. user can be used to retrieve username in other
# formats also.
password_query = SELECT username AS user,password FROM mailbox WHERE username = '%u' AND active='1'
# Query to retrieve user information, note uid matches dovecot.conf AND Postfix virtual_uid_maps parameter.
user_query = SELECT '/var/vmail/mail/' || maildir AS home, 8 as uid, 8 as gid FROM mailbox WHERE username = '%u' AND active = '1'
```

@ -1,48 +0,0 @@
*Description
This extension adds support for password expiration.
It is designed to have expiration on users passwords. An email is sent when the password is expiring in 30 days, then 14 days, then 7 days.
It is strongly inspired by https://abridge2devnull.com/posts/2014/09/29/dovecot-user-password-expiration-notifications-updated-4122015/, and adapted to fit with Postfix Admin & Roundcube's password plugin
Expiration unit is day
Expiration value for domain is set through Postfix Admin GUI
*Installation
Perform the following changes:
**Changes in MySQL/MariaDB mailbox table (as defined in $CONF['database_tables'] from config.inc.php):
You are invited to backup your DB first, and ensure the table name is correct.
Execute the attached SQL script (password_expiration.sql) that will add the required columns. The expiration value for existing users will be set to 90 days. If you want a different value, edit line 2 in the script and replace 90 by the required value.
**Changes in Postfix Admin :
To enable password expiration, add the following to your config.inc.php file:
$CONF['password_expiration'] = 'YES';
All my tests are performed using $CONF['encrypt'] = 'md5crypt';
**If you are using Roundcube's password plugin, you should also adapt the $config['password_query'] value.
I recommend to use:
$config['password_query'] = 'UPDATE mailbox SET password=%c, modified = now(), password_expiry = now() + interval 90 day';
of cource you may adapt to the expected expiration value
All my tests are performed using $config['password_algorithm'] = 'md5-crypt';
**Changes in Dovecot (adapt if you use another LDA)
Edit dovecot-mysql.conf file, and replace the user_query (and only this one) by this query:
password_query = SELECT username as user, password, concat('/var/vmail/', maildir) as userdb_var, concat('maildir:/var/vmail/', maildir) as userdb_mail, 20001 as userdb_uid, 20001 as userdb_gid, m.domain FROM mailbox m, domain d where d.domain = m.domain and m.username = '%u' AND m.active = '1' AND (m.password_expiry > now() or d.password_expiry = 0)
Of course you may require to adapt the uid, gid, maildir and table to your setup
**Changes in system
You need to have a script running on a daily basis to check password expiration and send emails 30, 14 and 7 days before password expiration (script attached: check_mailpass_expiration.sh).
Edit the script to adapt the variables to your setup.
This script is using postfixadmin.my.cnf to read credentials. Edit this file to enter a DB user that is allowed to access (read-write) your database. This file should be protected from any user (chmod 400).

@ -1,44 +0,0 @@
Security and PostfixAdmin
-------------------------
While the developers of PostfixAdmin believe the software to be
secure, there is no guarantee that it will continue to do be so
in the future - especially as new types of exploit are discovered.
(After all, this software is without warranty!)
In the event you do discover a vulnerability in this software,
please report it to the development mailing list, or contact
one of the developers directly.
DATABASE USER SECURITY
----------------------
You may wish to consider the following :
1. Postfix only requires READ access to the database tables.
2. The virtual vacation support (if used) only needs to WRITE to
the vacation_notification table (and read alias and vacation).
3. PostfixAdmin itself needs to be able to READ and WRITE to
all the tables.
4. PostfixAdmin's setup.php additionally needs permissions to CREATE
and ALTER tables in the PostfixAdmin database. For PostgreSQL, also
permissions for CREATE FUNCTION and CREATE TRIGGER are needed.
In other words: setup.php needs all permissions on the PostfixAdmin
database.
Using the above, you can improve security by creating separate
database user accounts for each of the above roles, and limit
the permissions available to them as appropriate.
FILE SYSTEM SECURITY
--------------------
PostfixAdmin does not require write support on the underlying
filesystem with the following exceptions:
- the templates_c directory where Smarty caches the templates
- PHP's session.save_path to store session files

@ -1,16 +0,0 @@
------------------------------------
Recreating a superadmin account
When you run setup.php you will be required to enter a super user name and password.
This user will be able to login and modify any domain or setting. Hence, superadmin!.
With that login you can create new superadmins (and you should delete or change the
password of admin@domain.tld). If that user is no longer there or you didn't use
the .TXT files, you could add another manually from the database.
In case you forgot your superadmin username or password, you can create a new
superadmin account using setup.php.
If you also have forgotten your setup password, you can use setup.php to configure
a new setup password.

@ -1,119 +0,0 @@
#
# Postfix Admin
# by Mischa Peters <mischa at high5 dot net>
# Copyright (c) 2002 - 2005 High5!
# Licensed under GPL for more info check GPL-LICENSE.TXT
#
REQUIRED!!
----------
- You are using Postfix 2.0 or higher.
- You are using Apache 1.3.27 / Lighttpd 1.3.15 or higher.
- You are using PHP 5.1.2 or higher.
- You are using MySQL 3.23 or higher OR PostgreSQL v7.4+
READ THIS FIRST!
----------------
This document describes upgrading from an older PostfixAdmin version
(>= v1.5x)
It's recommend that you install Postfix Admin in a new folder and not
on-top of the old install!! (At the very least, make sure you have backups of
the database and relevant filesystem!)
When upgrading Postfix Admin, make sure you backup your database before
running upgrade.php.
1. Backup the Database
----------------------
When you install from a previous version make sure you backup your database
first. There are a lot of changes in the database structure since Postfix Admin
1.5.4.
$ mysqldump -u root -p postfixdb > /tmp/postfixadmin-backup.sql
or
$ pg_dump -ad -u postfix postfixdb > /tmp/postfixadmin-backup.sql
(Replace postfixdb with your Postfixadmin database's name)
2. Unarchive new Postfix Admin
------------------------------
Make sure that you are in your WWW directory and then unarchive the
Postfix Admin archive (whatever the filename is):
$ tar -zxvf postfixadmin-X.X.tgz
3. Change permissions
----------------------
Since the database password is stored in the config.inc.php it's a good idea
to have change the permissions for Postfix Admin.
$ cd /usr/local/www/postfixadmin
$ find -type f -print0 | xargs -0 chmod 640
$ find -type f -print0 | xargs -0 chown root:www-data
(the last command assumes your Apache is running with group "www-data")
Since version 3.0 we use smarty templates. That means the templates_c directory
needs to be writeable for your webserver.
$ cd /usr/local/www/postfixadmin
$ mkdir templates_c && chmod 750 templates_c && chown -R www-data templates_c
(if your Apache runs as user "www-data")
If you have SELinux enabled, also run (adust the path to match your setup)
$ sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/utils/pfadmin/public/templates_c(/.*)?"
$ sudo restorecon -Rv /var/www/utils/pfadmin/
4. Configure
------------
Check the config.inc.php file. There you can specify settings that are
relevant to your setup.
Comparing config.inc.php with your previous using "diff" might save you some
time.
You can use a config.local.php file to contain your local settings.
These will override any defined in config.inc.php - and save some time when upgrading to a new version of PostfixAdmin ;-)
5. Run setup.php
----------------------------------------
Access setup.php through a web browser.
It will attempt to upgrade your database, and also allow you to create a superadmin user.
(In case the database upgrade fails, you can run setup.php?debug=1 to see the last executed query.)
From version 2.3, you need to specify a setup_password in config.inc.php -
setup.php should guide you through this process. If you do not have a setup_password, type one
into the form, and setup.php will echo out the hashed value (which needs to go into config.inc.php).
The setup_password removes the requirement for you to delete setup.php, and also closes a security hole.
Since version 2.2 of Postfixadmin, setup.php can perform the needed database
updates automatically .
If you update from 2.1 or older, also create a superadmin account using setup.php.
Note that admin/ has been merged into the main directory. Login with the
superadmin account to setup domains and domain admins.
6. Upgrade your postfix config
------------------------------
Since version 2.3, PostfixAdmin supports alias domains ($CONF['alias_domain']).
If you want to use them, you have to add some queries to your postfix config -
see POSTFIX_CONF for details.
7. Done
-------
This is all that is needed. Fire up your browser and go to the site that you
specified to host Postfix Admin.

@ -1,2 +0,0 @@
Random Screenshots taken on 2007/09/25, using a version of Postfixadmin from subversion.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

@ -1,281 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

@ -1,199 +0,0 @@
#
# Postfix Admin
# by Mischa Peters <mischa at high5 dot net>
# Copyright (c) 2002 - 2005 High5!
# Licensed under GPL for more info check GPL-LICENSE.TXT
#
REQUIREMENTS
------------
- Postfix
- Apache / Lighttpd
- PHP (for web server)
- one of the following databases:
- MariaDB/MySQL
- PostgreSQL
- SQLite
READ THIS FIRST!
----------------
When this is an upgrade from a previous version of Postfix Admin, please read
DOCUMENTS/UPGRADE.TXT also!
If you need to setup Postfix to be able to handle Virtual Domains and Virtual
Users check out:
- the PostfixAdmin documentation in the DOCUMENTS/ directory
- our wiki at https://sourceforge.net/p/postfixadmin/wiki/
There are also lots of HOWTOs around the web. Be warned that many of them
(even those listed below) may be outdated or incomplete.
Please stick to the PostfixAdmin documentation, and use those HOWTOs only if
you need some additional information that is missing in the PostfixAdmin
DOCUMENTS/ folder.
- http://bliki.rimuhosting.com/space/knowledgebase/linux/mail/postfixadmin+on+debian+sarge (Postfix+MySQL+Postfixadmin+Dovecot)
- http://en.gentoo-wiki.com/wiki/Virtual_mail_server_using_Postfix,_Courier_and_PostfixAdmin (Postfix+MySQL+Postfixadmin+Courier)
1. Unarchive new Postfix Admin
------------------------------
(if you installed PostfixAdmin as RPM or DEB package, you can obviously skip this step.)
Assuming we are installing Postfixadmin into /srv/postfixadmin, then something like this should work. Please check https://github.com/postfixadmin/postfixadmin/releases to get the latest stable release first (the 3.2.4 version/url below is probably stale)
$ cd /srv/
$ wget -O postfixadmin.tgz https://github.com/postfixadmin/postfixadmin/archive/postfixadmin-3.2.4.tar.gz
$ tar -zxvf postfixadmin.tgz
$ mv postfixadmin-postfixadmin-3.2 postfixadmin
Alternatively :
$ cd /srv
$ git clone https://github.com/postfixadmin/postfixadmin.git
$ cd postfixadmin
$ git checkout postfixadmin-3.2.4
2. Setup Web Server
-------------------
Assuming /var/www/html is where your webserver reads from, either create a symlink:
$ ln -s /srv/postfixadmin/public /var/www/html/postfixadmin
or setup an alias in your webserver config. For Apache, use:
Alias /postfixadmin /srv/postfixadmin/public
3. Setup a Database
-------------------
With your chosen/preferred database server (i.e. MySQL or PostgreSQL),
you need to create a new database. A good name for this could be :
postfix
The mechanics of creating the database vary depending on which server
you are using. Most users will find using phpMyAdmin or phpPgAdmin the
easiest route.
If you wish to use the command line, you'll need to do something like :
For MySQL:
CREATE DATABASE postfix;
CREATE USER 'postfix'@'localhost' IDENTIFIED BY 'choose_a_password';
GRANT ALL PRIVILEGES ON `postfix` . * TO 'postfix'@'localhost';
FLUSH PRIVILEGES;
For PostgreSQL:
CREATE USER postfix WITH PASSWORD 'whatever';
CREATE DATABASE postfix OWNER postfix ENCODING 'unicode';
For SQLite:
$mkdir /srv/postfixadmin/database
$touch /srv/postfixadmin/database/postfixadmin.db
$sudo chown -R www-data:www-data /srv/postfixadmin/database
(both the directory and the database need to be writeable)
4. Configure PostfixAdmin so it can find the database
-----------------------------------------------------
Create /srv/postfixadmin/config.local.php file for your local configuration:
<?php
$CONF['database_type'] = 'mysqli';
$CONF['database_user'] = 'postfix';
$CONF['database_password'] = 'postfixadmin';
$CONF['database_name'] = 'postfix';
$CONF['configured'] = true;
?>
See config.inc.php for all available config options and their default value.
You can also edit config.inc.php instead of creating a config.local.php,
but this will make updates harder and is therefore not recommended.
The most important settings are those for your database server.
You must also change the line that says :
$CONF['configured'] = false;
to
$CONF['configured'] = true;
PostfixAdmin does not require write access to any files except the templates_c
directory (smarty cache). You can therefore leave the files owned by root (or
another user); as long as the web server user (e.g. www-data) can read them, it
will be fine.
For templates_c/, allow write access (only) for the web server user (e. g. www-data).
The easiest way to do this is
$ mkdir -p /srv/postfixadmin/templates_c
$ chown -R www-data /srv/postfixadmin/templates_c
(If you're using e.g. CentOS or another distribution which enables SELinux, something like the following may be necessary as well :
```chcon -R -t httpd_sys_content_rw_t /usr/share/postfixadmin/templates_c```
)
5. Check settings, and create Admin user
----------------------------------------
Hit http://yourserver.tld/postfixadmin/setup.php in a web browser.
You should see a list of 'OK' messages.
The setup.php script will attempt to create the database structure
(or upgrade it if you're coming from a previous version).
Assuming everything is OK you can specify a password (which you'll
need to use setup.php again in the future); when you submit the form,
the hashed value (which you need to enter into config.inc.php is echoed
out - with appropriate instructions on what to do with it).
create the admin user using the form displayed.
6. Use PostfixAdmin
-------------------
This is all that is needed. Fire up your browser and go to the site that you
specified to host Postfix Admin.
7. Integration with Postfix, Dovecot etc.
-----------------------------------------
Now that PostfixAdmin is working, you need to do some configuration in Postfix,
Dovecot etc. so that they use the domains, mailboxes and aliases you setup in
PostfixAdmin.
The files in the DOCUMENTS/ directory explain which settings you need to
do/change.
7. XMLRPC Integration (OPTIONAL!)
--------------------------------
See ADDITIONS/squirrelmail-plugin
See xmlrpc.php - only a subset of Postfixadmin's functionality is currently exposed.
See config.inc.php - see xmlrpc_enabled key (defaults to off).
You'll need to install a copy of the Zend Framework (version 1.12.x) within Postfixadmin
or your PHP include_path (see header within xmlrpc.php).
NOTE: The XMLRPC interface is _not compatible_ with Zend Framework version 2.x.
You'll need to enable the xmlrpc link (see config.inc.php)
8. More information
-------------------
The code and issue tracker is on GitHub:
https://github.com/postfixadmin/postfixadmin
IRC - a community of people may be able to help in #postfixadmin on irc.freenode.net.
See http://webchat.freenode.net/
Legacy forum posts are on SourceForce at
https://sourceforge.net/projects/postfixadmin

@ -1,46 +0,0 @@
Postfix Admin is a Web Based Management tool created for Postfix. It is
a PHP based application that handles Postfix Style Virtual Domains and
Users that are stored in MySQL.
Copyright (c) 2005 High5! (Mischa Peters and others)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Postfix Admin version 2.1.1, Copyright (c) 2005 High5! (Mischa Peters & Contributors)
Postfix Admin comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
High5!, hereby disclaims all copyright interest in the program
`Postfix Admin' (which makes passes at Postfix, PHP and MySQL) written
by Wietse Venema, PHP Group and MYSQL AB.
Contributors: Mihau, Tarvin, SteveB, DJTremors, WhiteFox, David Osborn,
David Goodwin (GingerDog), Christian Boltz (cboltz) and GregC and others.
Postfix Admin uses some libraries that come with a different license.
a) libraries shipped with PostfixAdmin
- the Smarty templating engine is licensed under the GNU LESSER GENERAL PUBLIC
LICENSE Version 3 (see smarty/COPYING.lib)
- the CLI (commandline interface) is based on CakePHP which is licensed under
the MIT license.
b) libraries not shipped with PostfixAdmin
- the XMLRPC interface and the squirrelmail plugin use the Zend Framework which is
licensed under the New BSD License (3-clause), see http://framework.zend.com/license
- PHPUnit (used in tests/) is licensed under the BSD License (3-clause).

@ -1,41 +0,0 @@
![GitHubBuild](https://github.com/postfixadmin/postfixadmin/workflows/GitHubBuild/badge.svg)
[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/postfixadmin/Lobby)
[![Coverage Status](https://coveralls.io/repos/github/postfixadmin/postfixadmin/badge.svg?branch=master)](https://coveralls.io/github/postfixadmin/postfixadmin?branch=master)
![GitHub repo size](https://img.shields.io/github/repo-size/postfixadmin/postfixadmin)
[![Chat](https://img.shields.io/badge/chat-on%20freenode-brightgreen.svg)](https://kiwiirc.com/nextclient/irc.freenode.net/#postfixadmin)
# PostfixAdmin
An open source, web based interface for managing domains/mailboxes/aliases etc on a Postfix based mail server.
Integrates with :
- Postfix
- IMAP/POP3 server (e.g. Dovecot or Courier)
- Database backend (choose one of: sqlite, mysql, postgresql)
- Fetchmail (optional)
## Features
- Unlimited domains/aliases/mailboxes
- Optional storage quota support
- Optional password expiry (beta)
- Multiple password hashing formats
- Supports PostgreSQL, MySQL, MariaDB, SQLite database backends (choose one)
- Supports retrieval of mail from a remote POP3 server (via fetchmail)
- Vacation / Autoresponder / Out Of Office support
- Users have the ability to login, change their password or vacation (out of office) status.
- Integration with Squirrelmail / Roundcube (via plugins)
- Optional XMLRPC based API
- Supports PHP5.6+
## Useful Links
- [Probably all you need to read (pdf)](http://blog.cboltz.de/uploads/postfixadmin-30-english.pdf)
- http://postfixadmin.sf.net - the current homepage for the project
- [Docker Images](https://github.com/postfixadmin/docker)
- [What is it? (txt)](/DOCUMENTS/POSTFIXADMIN.txt)
- [Installation instructions](/INSTALL.TXT)
- [Wiki](https://sourceforge.net/p/postfixadmin/wiki/)
- [Mailing list](https://sourceforge.net/p/postfixadmin/discussion/676076)
- [IRC channel](irc://irc.freenode.net/postfixadmin) (#postfixadmin on irc.freenode.net).

@ -1,93 +0,0 @@
This file is not exhaustive.
Please feel free to add yourself and a summary of changes to this file at the bottom if creating a pull request.
Postfixadmin was originally written by Mischa Peters <mischa at high5 dot net>
Copyright (c) 2002 - 2005 High5!
Licensed under GPL for more info check GPL-LICENSE.TXT
Additional authors:
2004/07/13 David Osborn <ossdev at daocon.com>
strict, processes domain level aliases, more
subroutines, send reply from original to address
2004/11/09 David Osborn <ossdev at daocon.com>
Added syslog support
Slightly better logging which includes messageid
Avoid infinite loops with domain aliases
2005-01-19 Troels Arvin <troels at arvin.dk>
PostgreSQL-version.
Normalized DB schema from one vacation table ("vacation")
to two ("vacation", "vacation_notification"). Uses
referential integrity CASCADE action to simplify cleanup
when a user is no longer on vacation.
Inserting variables into queries stricly by prepare()
to try to avoid SQL injection.
International characters are now handled well.
2005-01-21 Troels Arvin <troels at arvin.dk>
Uses the Email::Valid package to avoid sending notices
to obviously invalid addresses.
2007-08-15 David Goodwin <david at palepurple.co.uk>
Use the Perl Mail::Sendmail module for sending mail
Check for headers that start with blank lines (patch from forum)
2007-08-20 Martin Ambroz <amsys at trustica.cz>
Added initial Unicode support
2008-05-09 Fabio Bonelli <fabiobonelli at libero.it>
Properly handle failed queries to vacation_notification.
Fixed log reporting.
2008-07-29 Patch from Luxten to add repeat notification after timeout. See:
https://sourceforge.net/tracker/index.php?func=detail&aid=2031631&group_id=191583&atid=937966
2008-08-01 Luigi Iotti <luigi at iotti dot biz>
Use envelope sender/recipient instead of using
From: and To: header fields;
Support to good vacation behavior as in
http://www.irbs.net/internet/postfix/0707/0954.html
(needs to be tested);
2008-08-04 David Goodwin <david at palepurple dot co dot uk>
Use Log4Perl
Added better testing (and -t option)
2009-06-29 Stevan Bajic <stevan at bajic.ch>
Add Mail::Sender for SMTP auth + more flexibility
2009-07-07 Stevan Bajic <stevan at bajic.ch>
Add better alias lookups
Check for more heades from Anti-Virus/Anti-Spam solutions
2009-08-10 Sebastian <reg9009 at yahoo dot de>
Adjust SQL query for vacation timeframe. It is now possible to set from/until date for vacation message.
2012-04-1 Nikolaos Topp <info at ichier.de>
Add configuration parameter $smtp_client in order to get mails through
postfix helo-checks, using check_helo_access whitelist without permitting 'localhost' default style stuff
2012-04-19 Jan Kruis <jan at crossreference dot nl>
change SQL query for vacation into function.
Add sub get_interval()
Gives the user the option to set the interval time ( 0 = one reply, 1 = autoreply, > 1 = Delay reply )
See https://sourceforge.net/tracker/?func=detail&aid=3508083&group_id=191583&atid=937966
2012-06-18 Christoph Lechleitner <christoph.lechleitner@iteg.at>
Add capability to include the subject of the original mail in the subject of the vacation message.
A good vacation subject could be: 'Re: $SUBJECT'
Also corrected log entry about "Already informed ..." to show the $orig_from, not $email
2017-07-14 Thomas Kempf <tkempf@hueper.de>
Replacing deprecated Mail::Sender by Email::Sender
Add configuration parameter $no_vacation_pattern in order to exlude specific alias-recipients from
sending vacation mails, even if one or multiple of the recipients the alias points to has vacation
currently active.

@ -1,512 +0,0 @@
Introduction
============
This is a very first implementation of Postfix content filtering.
A Postfix content filter receives unfiltered mail from Postfix and
does one of the following:
- re-injects the mail back into Postfix, perhaps after changing content
- rejects the mail (by sending a suitable status code back to
Postfix) so that it is returned to sender.
- sends the mail somewhere else
This document describes two approaches to content filtering: simple
and advanced. Both filter all the mail by default.
At the end are examples that show how to filter only mail from
users, about using different filters for different domains that
you provide MX service for, and about selective filtering on the
basis of message envelope and/or header/body patterns.
Simple content filtering example
================================
The first example is simple to set up. It uses a shell script that
receives unfiltered mail from the Postfix pipe delivery agent, and
that feeds filtered mail back into the Postfix sendmail command.
Only mail arriving via SMTP will be content filtered.
..................................
: Postfix :
Unfiltered mail----->smtpd \ /local---->Filtered mail
: -cleanup->queue- :
---->pickup / \smtp----->Filtered mail
^ : | :
| : \pipe-----+
| .................................. |
| |
| |
+-Postfix sendmail<----filter script<--+
Mail is filtered by a /some/where/filter program. This can be a
simple shell script like this:
#!/bin/sh
# Localize these.
INSPECT_DIR=/var/spool/filter
SENDMAIL="/usr/sbin/sendmail -i"
# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
# Clean up when done or when aborting.
trap "rm -f in.$$" 0 1 2 3 15
# Start processing.
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
# filter <in.$$ || { echo Message content rejected; exit $EX_UNAVAILABLE; }
$SENDMAIL "$@" <in.$$
exit $?
The idea is to first capture the message to file and then run the
content through a third-party content filter program.
- If the mail cannot be captured to file, mail delivery is deferred
by terminating with exit status 75 (EX_TEMPFAIL). Postfix will
try again after some delay.
- If the content filter program finds a problem, the mail is bounced
by terminating with exit status 69 (EX_UNAVAILABLE). Postfix
will return the message to the sender as undeliverable.
- If the content is OK, it is given as input to the Postfix sendmail
command, and the exit status of the filter command is whatever
exit status the Postfix sendmail command produces. Postfix will
deliver the message as usual.
I suggest that you run this script by hand until you are satisfied
with the results. Run it with a real message (headers+body) as
input:
% /some/where/filter -f sender recipient... <message-file
Once you're satisfied with the content filtering script:
1 - Create a dedicated local user account called "filter". This
user handles all potentially dangerous mail content - that is
why it should be a separate account. Do not use "nobody", and
most certainly do not use "root" or "postfix". The user will
never log in, and can be given a "*" password and non-existent
shell and home directory.
2 - Create a directory /var/spool/filter that is accessible only
to the "filter" user. This is where the content filtering script
is supposed to store its temporary files.
3 - Define the content filter in the Postfix master file:
/etc/postfix/master.cf:
filter unix - n n - - pipe
flags=Rq user=filter argv=/somewhere/filter -f ${sender} -- ${recipient}
To turn on content filtering for mail arriving via SMTP only, append
"-o content_filter=filter:dummy" to the master.cf entry that defines
the Postfix SMTP server:
/etc/postfix/master.cf:
smtp inet ...stuff... smtpd
-o content_filter=filter:dummy
The content_filter configuration parameter accepts the same syntax
as the right-hand side in a Postfix transport table. Execute
"postfix reload" to complete the change.
To turn off content filtering, edit the master.cf file, remove the
"-o content_filter=filter:dummy" text from the entry that defines
the Postfix SMTP server, and execute another "postfix reload".
With the shell script as shown above you will lose a factor of four
in Postfix performance for transit mail that arrives and leaves
via SMTP. You will lose another factor in transit performance for
each additional temporary file that is created and deleted in the
process of content filtering. The performance impact is less for
mail that is submitted or delivered locally, because such deliveries
are already slower than SMTP transit mail.
Simple content filter limitations
=================================
The problem with content filters like the one above is that they
are not very robust. The reason is that the software does not talk
a well-defined protocol with Postfix. If the filter shell script
aborts because the shell runs into some memory allocation problem,
the script will not produce a nice exit status as defined in the
file /usr/include/sysexits.h. Instead of going to the deferred
queue, mail will bounce. The same lack of robustness can happen
when the content filtering software itself runs into a resource
problem.
Advanced content filtering example
===================================
The second example is more complex, but can give much better
performance, and is less likely to bounce mail when the machine
runs into a resource problem. This approach uses content filtering
software that can receive and deliver mail via SMTP.
Some Anti-virus software is built to receive and deliver mail via
SMTP and is ready to use as an advanced Postfix content filter.
For non-SMTP capable content filtering software, Bennett Todd's
SMTP proxy implements a nice PERL/SMTP content filtering framework.
See: http://bent.latency.net/smtpprox/
The example given here filters all mail, including mail that arrives
via SMTP and mail that is locally submitted via the Postfix sendmail
command.
You can expect to lose about a factor of two in Postfix performance
for transit mail that arrives and leaves via SMTP, provided that
the content filter creates no temporary files. Each temporary file
created by the content filter adds another factor to the performance
loss.
We will set up a content filtering program that receives SMTP mail
via localhost port 10025, and that submits SMTP mail back into
Postfix via localhost port 10026.
..................................
: Postfix :
----->smtpd \ /local---->
: -cleanup->queue- :
---->pickup / ^ | \smtp----->
: | v :
: smtpd smtp :
: 10026 | :
......................|...........
^ |
| v
....|............
: | 10025 :
: filter :
: :
.................
To enable content filtering in this manner, specify in main.cf a
new parameter:
/etc/postfix/main.cf:
content_filter = scan:localhost:10025
This causes Postfix to add one extra content filtering record to
each incoming mail message, with content scan:localhost:10025.
The content filtering records are added by the smtpd and pickup
servers.
When a queue file has content filtering information, the queue
manager will deliver the mail to the specified content filter
regardless of its final destination.
In this example, "scan" is an instance of the Postfix SMTP client
with slightly different configuration parameters. This is how
one would set up the service in the Postfix master.cf file:
/etc/postfix/master.cf:
scan unix - - n - 10 smtp
Instead of a limit of 10 concurrent processes, use whatever process
limit is feasible for your machine. Content inspection software
can gobble up a lot of system resources, so you don't want to have
too much of it running at the same time.
The content filter can be set up with the Postfix spawn service,
which is the Postfix equivalent of inetd. For example, to instantiate
up to 10 content filtering processes on demand:
/etc/postfix/master.cf:
localhost:10025 inet n n n - 10 spawn
user=filter argv=/some/where/filter localhost 10026
"filter" is a dedicated local user account. The user will never
log in, and can be given a "*" password and non-existent shell and
home directory. This user handles all potentially dangerous mail
content - that is why it should be a separate account.
In the above example, Postfix listens on port localhost:10025. If
you want to have your filter listening on port localhost:10025
instead of Postfix, then you must run your filter as a stand-alone
program.
Note: the localhost port 10025 SMTP server filter should announce
itself as "220 localhost...". Postfix aborts delivery when it
connects to an SMTP server that uses the same hostname as Postfix
("host <servername> greeted me with my own hostname"), because that
normally means you have a mail delivery loop problem.
The example here assumes that the /some/where/filter command is a
PERL script. PERL has modules that make talking SMTP easy. The
command-line specifies that mail should be sent back into Postfix
via localhost port 10026.
The simplest content filter just copies SMTP commands and data
between its inputs and outputs. If it has a problem, all it has to
do is to reply to an input of `.' with `550 content rejected', and
to disconnect without sending `.' on the connection that injects
mail back into Postfix.
The job of the content filter is to either bounce mail with a
suitable diagnostic, or to feed the mail back into Postfix through
a dedicated listener on port localhost 10026:
/etc/postfix/master.cf:
localhost:10026 inet n - n - 10 smtpd
-o content_filter=
-o local_recipient_maps=
-o relay_recipient_maps=
-o myhostname=localhost.domain.tld
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
Warning for Postfix version 2 users: in this SMTP server after the
content filter, do not override main.cf settings for virtual_alias_maps
or virtual_alias_domains. That would cause mail to be rejected with
"User unknown".
This SMTP server has the same process limit as the "filter" master.cf
entry.
The "-o content_filter=" requests no content filtering for incoming
mail.
The "-o local_recipient_maps=" and "-o relay_recipient_maps=" avoid
unnecessary table lookups.
The "-o myhostname=localhost.domain.tld" avoids false alarms ("host
<servername> greeted me with my own hostname") if your content
filter is based on a proxy that simply relays SMTP commands.
The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
turn off UCE controls that would only waste time here.
Squeezing out more performance
==============================
Many refinements are possible, such as running a specially-configured
smtp delivery agent for feeding mail into the content filter, and
turning off address rewriting before content filtering.
As the example below shows, things quickly become very complex,
because a lot of main.cf like information gets listed in the
master.cf file. This makes the system hard to understand.
Even worse, details change as Postfix evolves and different
configuration parameters are implemented by different programs.
If you need to squeeze out more performance, it is probably simpler
to run multiple Postfix instances, one before and one after the
content filter. That way, each instance can have simple main.cf
and master.cf files, each instance can have its own mail queue,
and the system will be easier to understand.
As before, we will set up a content filtering program that receives
SMTP mail via localhost port 10025, and that submits SMTP mail back
into Postfix via localhost port 10026.
.......................................
: Postfix :
----->smtpd \ :
: -pre-cleanup-\ /local---->
---->pickup / -queue- :
: -cleanup-/ | \smtp----->
: bounces/ ^ v :
: and locally | v :
: forwarded smtpd scan :
: messages 10026 | :
...........................|...........
^ |
| v
....|.............
: | 10025 :
: filter :
: :
..................
To enable content filtering in this manner, specify in main.cf a
new parameter:
/etc/postfix/main.cf:
content_filter = scan:localhost:10025
/etc/postfix/master.cf:
#
# These are the usual input "smtpd" and local "pickup" servers already
# present in master.cf. We add an option to select a non-default
# cleanup service (defined further below).
#
smtp inet n - n - - smtpd
-o cleanup_service_name=pre-cleanup
pickup fifo n - n 60 1 pickup
-o cleanup_service_name=pre-cleanup
#
# ------------------------------------------------------------------
#
# This is the cleanup daemon that handles messages in front of
# the content filter. It does header_checks and body_checks (if
# any), but does no virtual alias or canonical address mapping,
# so that mail passes through your content filter with the original
# recipient addresses mostly intact.
#
# Virtual alias or canonical address mapping happens in the second
# cleanup phase after the content filter. This gives the content_filter
# access to *largely* unmodified addresses for maximum flexibility.
#
# Some sites may specifically want to perform canonical or virtual
# address mapping in front of the content_filter. In that case you
# still have to enable address rewriting in the after-filter cleanup
# instance, in order to correctly process forwarded mail or bounced
# mail.
#
pre-cleanup unix n - n - 0 cleanup
-o canonical_maps=
-o sender_canonical_maps=
-o recipient_canonical_maps=
-o masquerade_domains=
-o virtual_alias_maps=
#
# ------------------------------------------------------------------
#
# This is the delivery agent that injects mail into the content
# filter. It is tuned for low concurrency, because most content
# filters burn CPU and use lots of memory. The process limit of 10
# re-enforces the effect of $default_destination_concurrency_limit.
# Even without an explicit process limit, the concurrency is bounded
# because all messages heading into the content filter have the same
# destination.
#
scan unix - - n - 10 smtp
#
# ------------------------------------------------------------------
#
# This is the SMTP listener that receives filtered messages from
# the content filter. It *MUST* clear the content_filter
# parameter to avoid loops, and use a different hostname to avoid
# triggering the Postfix SMTP loop detection code.
#
# This "smtpd" uses the normal cleanup service which is also used
# for bounces and for internally forwarded mail.
#
# The parameters from mynetworks onward disable all access
# control other than insisting on connections from one of the IP
# addresses of the host. This is typically overkill, but can
# reduce resource usage, if the default restrictions use lots of
# tables.
#
localhost:10026 inet n - n - - smtpd
-o content_filter=
-o myhostname=localhost.domain.tld
-o local_recipient_maps=
-o relay_recipient_maps=
-o mynetworks=127.0.0.0/8
-o mynetworks_style=host
-o smtpd_restriction_classes=
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
#
# Do not override main.cf settings here for virtual_alias_maps or
# virtual_mailbox_maps. This causes mail to be rejected with "User
# unknown in virtual (alias|mailbox) recipient table".
#
# ------------------------------------------------------------------
#
# This is the normal cleanup daemon for use after content filtering.
# No header or body checks, because those have already been taken
# care of by the pre-cleanup service before the content filter.
#
# The normal cleanup instance does all the virtual alias and canonical
# address mapping that was disabled in the pre-cleanup instance before
# the content filter. This rewriting must be done even when you didn't
# disable address rewriting in the pre-cleanup instance, in order to
# correctly process bounces and locally forwarded mail.
#
cleanup unix n - n - 0 cleanup
-o header_checks=
-o mime_header_checks=
-o nested_header_checks=
-o body_checks=
#
# ------------------------------------------------------------------
#
# The normal "smtp" delivery agent for contrast with "scan".
#
smtp unix - - n - - smtp
The above example causes Postfix to add one content filtering record
to each incoming mail message, with content scan:localhost:10025.
You can use the same syntax as in the right-hand side of a Postfix
transport table. The content filtering records are added by the
smtpd and pickup servers.
The "scan" transport is a dedicated instance of the "smtp" delivery
agent for injecting messages into the SMTP content filter. Using
a dedicated "smtp" transport allows one to tune it for the specific
task of delivering mail to a local content filter (low latency,
low concurrency, throughput dependent on predictably low latency).
See the previous example for setting up the content filter with
the Postfix spawn service; you can of course use any server that
can be run stand-alone outside the Postfix environment.
Filtering mail from outside users only
======================================
The easiest approach is to configure ONE Postfix instance with TWO
SMTP server addresses in master.cf:
- One SMTP server address for inside users only that never invokes
content filtering.
- One SMTP server address for outside users that always invokes
content filtering.
/etc/postfix.master.cf:
# SMTP service for internal users only, no content filtering.
1.2.3.4:smtp inet n - n - - smtpd
-o smtpd_client_restrictions=permit_mynetworks,reject
127.0.0.1:smtp inet n - n - - smtpd
-o smtpd_client_restrictions=permit_mynetworks,reject
# SMTP service for external users, with content filtering.
1.2.3.5:smtp inet n - n - - smtpd
-o content_filter=foo:bar
Getting really nasty
====================
The above filtering configurations are static. Mail that follows
a given path is either always filtered or it is never filtered. As
of Postfix 2.0 you can also turn on content filtering on the fly.
The Postfix UCE features allow you to specify a filtering action
on the fly:
FILTER foo:bar
You can do this in smtpd access maps as well as the cleanup server's
header/body_checks. This feature must be used with great care:
you must disable all the UCE features in the after-filter smtpd
and cleanup daemons or else you will have a content filtering loop.
Limitations:
- There can be only one content filter action per message.
- FILTER actions from smtpd access maps and header/body_checks take
precedence over filters specified with the main.cf content_filter
parameter.
- Only the last FILTER action from smtpd access maps or from
header/body_checks takes effect.
- The same content filter is applied to all the recipients of a
given message.

@ -1,245 +0,0 @@
# About Virtual Vacation
AKA 'An out of office' automated email response.
The vacation script runs as service within Postfix's master.cf configuration file.
Mail is sent to the vacation service via a transport table mapping.
When users mark themselves as away on vacation, an alias is added to their account
sending a copy of all mail to them to the vacation service.
e.g. mail to billy@goat.com will be delivered to
* billy@goat.com AND
* billy#goat.com@autoreply.goat.com
Mail to @autoreply.goat.com is caught by the vacation.pl script and a reply
will be sent based on various settings. By default a reply is only sent once.
# Dependencies / Requirements
There are a bunch of Perl modules which need installing, depending on your
distribution these may be available through your package management tool, or
will need installing through CPAN.
```
Email::Valid
Email::Sender
Email::Simple
Email::Valid
Try::Tiny
MIME::Charset
MIME::EncWords
Log::Log4perl
Log::Dispatch
GetOpt::Std
Net::DNS;
```
You may install these via CPAN, or through your package tool.
CPAN: 'perl -MCPAN -e shell', then 'install Module::Whatever'
## Debian Systems
```bash
apt-get install libemail-sender-perl libemail-simple-perl libemail-valid-perl libtry-tiny-perl libdbd-pg-perl libemail-mime-perl liblog-log4perl-perl liblog-dispatch-perl libgetopt-argvfile-perl libmime-charset-perl libmime-encwords-perl libnet-dns-perl
```
and one of :
```bash
libdbd-pg-perl or libdbd-mysql-perl
```
# Installing Virtual Vacation
## 1. Create a local account
Create a dedicated local user account called "vacation".
This user handles all potentially dangerous mail content - that is why it
should be a separate account.
Do not use "nobody", and most certainly do not use "root" or "postfix". The
user will never log in, and can be given a "*" password and non-existent
shell and home directory.
Also create a separate "vacation" group.
This should look like this:
```raw
#/etc/passwd
vacation:*:65501:65501:Virtual Vacation:/nonexistent:/sbin/nologin
```
```raw
#/etc/group
vacation:*:65501:
```
## 2. Create a log directory or log file
If you want to log to a file ($log\_to\_file), create a log directory or an
empty log file.
This file or directory needs to be writeable for the "vacation" user.
Note: If you are logging to syslog, you can skip this step.
## 3. Install vacation.pl
Create a directory /usr/lib/postfixadmin/ and copy the vacation.pl file to it:
```bash
mkdir /usr/lib/postfixadmin
cp vacation.pl /usr/lib/postfixadmin/vacation.pl
chown -R root:vacation /usr/lib/postfixadmin
chmod 750 /usr/lib/postfixadmin/ /usr/lib/postfixadmin/vacation.pl
```
Which will then look something like:
```raw
-rwxr-x--- 1 root vacation 3356 Dec 21 00:00 vacation.pl*
```
## 4. Setup the transport type
Define the transport type in the Postfix master file:
```raw
#/etc/postfix/master.cf:
vacation unix - n n - - pipe
flags=Rq user=vacation argv=/usr/lib/postfixadmin/vacation.pl -f ${sender} -- ${recipient}
```
## 5. Setup the transport maps file
Tell Postfix to use a transport maps file, so add the following to your
Postfix main.cf:
```raw
#/etc/postfix/main.cf:
transport_maps = hash:/etc/postfix/transport
```
Then add the transport definition to the newly created transport file.
Obviously, change yourdomain.com to your own domain. This can be any
arbitrary domain, and it is easiest if you just choose one that will be used
for all your domains.
```raw
#/etc/postfix/transport
autoreply.yourdomain.com vacation:
```
(You may need to create an entry in /etc/hosts for your non-existant domain)
Execute
```bash
postmap /etc/postfix/transport
```
Execute
```bash
postfix reload
```
to complete the change.
## 6. Configure vacation.pl
The perl vacation.pl script needs to know which database you are using, and also
how to connect to the database.
Namely :
Change any variables starting with '$db\_' and '$db\_type' to either 'mysql' or 'pgsql'.
Change the $vacation\_domain variable to match what you entered in your /etc/postfix/transport
file.
You can do this in two ways:
a) edit vacation.pl directly (not recommended!)
b) create /etc/postfixadmin/vacation.conf and enter your settings there
Just use perl syntax there to fill the config variables listed in vacation.pl
(without the "our" keyword). Example:
```perl
$db_username = 'mail';
1; # required final line - keeps perl happy.
```
To make sure nobody except vacation.pl can read your vacation.conf (including the
database password), run
```bash
chown root:vacation /etc/postfixadmin/vacation.conf
chmod 640 /etc/postfixadmin/vacation.conf
```
## 7. Check the alias expansion
Depending on your setup, you may have multiple 'smtpd' service definitions within
your postfix master.cf file. This is especially the case if you are also using AMAVIS or
another content filtering system when mail is re-injected into Postfix using the smtpd daemon.
If you are, it's likely that alias expansion may happen more than once, in which case you
may see vacation-style responses duplicated. To suppress this behaviour, you need to add:
```raw
-o receive_override_options=no_address_mappings
```
For example :
```raw
smtp inet n - - - 12 smtpd
-o content_filter=amavis:[127.0.0.50]:10024
-o receive_override_options=no_address_mappings
127.0.0.1:10025 inet n - - - - smtpd
-o smtpd_autorized_xforward_hosts=127.0.0.0/8
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o receive_override_options=no_header_body_checks
```
^^^ Alias expansion occurs here, so we don't want it to happen again for the
first smtpd daemon (above). If you have per-user settings in amavis,
you might want to have no_address_mappings in the smtpd on port 10025
instead.
## 8. Security
If security is an issue for you, read ../DOCUMENTS/Security.txt
# Postfixadmin
When this is all in place you need to have a look at the Postfix Admin
config.inc.php. Here you need to enable Virtual Vacation for the site.
# Help ! It's not working
When something is not working there are a couple of files that you can have
a look at. The most important one is your maillog (usually in /var/log/).
Vacation.pl also has some debugging and logging capabilties. Check the top
of vacation.pl.

@ -1,22 +0,0 @@
Return-Path: <www-data@palepurple.co.uk>
X-Original-To: david@example.org
Delivered-To: david@example.org
Received: by mail.palepurple.co.uk (Postfix, from userid 33)
id 1942F894CF9; Fri, 1 Aug 2008 11:23:45 +0100 (BST)
To: "" <david@example.org>
Subject: New Phone call - annotate it!
X-PHP-Script: admin.palepurple.co.uk/contacts/dispatch.php for 78.105.97.55
From: "asterisk@example.org" <asterisk@example.org>
Date: Fri, 01 Aug 2008 11:23:45 +0100
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
Message-Id: <20080801102345.1942F894CF9@mail.palepurple.co.uk>
Content-Length: 250
Lines: 5
=0AVisit the following URL(s) to annotate these phone calls... :=0A=0A htt=
ps://admin.palepurple.co.uk/contacts/phone_communication/browse.php=0Ahttp=
s://admin.palepurple.co.uk/contacts/phone_communication/view.php?phone_com=
munication_id=3D3532

@ -1,55 +0,0 @@
Return-Path: <notification+meynbxsa@facebookmail.com>
X-Original-To: david@example.org
Delivered-To: david@example.org
Received: by mail.palepurple.co.uk (Postfix, from userid 1007)
id B735A894CF8; Mon, 4 Aug 2008 16:28:13 +0100 (BST)
Received: from localhost (localhost [127.0.0.1])
by mail.palepurple.co.uk (Postfix) with ESMTP id 79230894CF9
for <david@example.org>; Mon, 4 Aug 2008 16:28:13 +0100 (BST)
X-Virus-Scanned: by Amavis+SpamAssassin+ClamAV and more at palepurple.co.uk
X-Spam-Score: -3.565
X-Spam-Level:
X-Spam-Status: No, score=-3.565 tagged_above=-99 required=5 tests=[AWL=0.035,
BAYES_00=-2.599, RCVD_IN_DNSWL_LOW=-1, SPF_PASS=-0.001]
Received: from mail.palepurple.co.uk ([127.0.0.50])
by localhost (oak.palepurple.co.uk [127.0.0.50]) (amavisd-new, port 10024)
with ESMTP id AajG3+FXGWMd for <david@example.org>;
Mon, 4 Aug 2008 16:28:10 +0100 (BST)
Received: from mx-out.facebook.com (outmail003.ash1.tfbnw.net [69.63.184.103])
by mail.palepurple.co.uk (Postfix) with ESMTP id 36DD4894CF8
for <david@example.org>; Mon, 4 Aug 2008 16:28:09 +0100 (BST)
Received: from www.new.facebook.com (intlb01-mip1.sctm.tfbnw.net [10.1.240.6])
by mx-out.facebook.com [email023.ash1.facebook.com] (8.13.7/8.13.6) with ESMTP id m74FS8Oa030908
for <david@example.org>; Mon, 4 Aug 2008 08:28:09 -0700
X-Facebook: from zuckmail ([207.118.59.216])
by www.new.facebook.com with HTTP (ZuckMail);
Date: Mon, 4 Aug 2008 08:28:08 -0700
To: David Goodwin <david@example.org>
From: Facebook <notification+meynbxsa@facebookmail.com>
Reply-to: noreply <noreply@facebookmail.com>
Subject: Mark Spencer also commented on Jon Masters's note...
Message-ID: <dummycontentgoeshere27efe2cde474@www.new.facebook.com>
X-Priority: 3
X-Mailer: ZuckMail [version 1.00]
X-Facebook-Notify: note_reply
Errors-To: notification+meynbxsa@facebookmail.com
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset="UTF-8"
Content-Length: 374
Lines: 14
Mark also commented on Jon Masters's note "Visiting the UK"
To read all the comments, follow the link below:
http://www.facebook.com/n/?note.php&note_id=whatever
Thanks,
The Facebook Team
___
Want to control which emails you receive from Facebook? Go to:
http://www.facebook.com/editaccount.php?notifications&md=sheepmightfly

@ -1,43 +0,0 @@
Return-Path: <david@example.org>
X-Original-To: david@example.org
Delivered-To: david@example.org
Received: by mail.palepurple.co.uk (Postfix, from userid 1007)
id 83AE0894CF8; Tue, 5 Aug 2008 20:15:53 +0100 (BST)
Received: from localhost (localhost [127.0.0.1])
by mail.palepurple.co.uk (Postfix) with ESMTP id 4A249894CF9
for <david@example.org>; Tue, 5 Aug 2008 20:15:53 +0100 (BST)
X-Virus-Scanned: by Amavis+SpamAssassin+ClamAV and more at palepurple.co.uk
X-Spam-Score: -2.836
X-Spam-Level:
X-Spam-Status: No, score=-2.836 tagged_above=-99 required=5 tests=[AWL=-0.237,
BAYES_00=-2.599]
Received: from mail.palepurple.co.uk ([127.0.0.50])
by localhost (oak.palepurple.co.uk [127.0.0.50]) (amavisd-new, port 10024)
with ESMTP id gHB1TKpjKIKX for <david@example.org>;
Tue, 5 Aug 2008 20:15:50 +0100 (BST)
Received: from irc.palepurple.co.uk (irc.palepurple.co.uk [89.16.169.131])
by mail.palepurple.co.uk (Postfix) with ESMTP id CAF82894CF8
for <david@example.org>; Tue, 5 Aug 2008 20:15:50 +0100 (BST)
Received: by irc.palepurple.co.uk (Postfix, from userid 1000)
id 8869450146; Tue, 5 Aug 2008 20:15:50 +0100 (BST)
Date: Tue, 5 Aug 2008 20:15:50 +0100
From: David Goodwin <david@example.org>
To: david@example.org, fred@example.org, barney@example.org, rover@example.org,
roger@example.org
Subject: test email
Message-ID: <20080805191549.GA27905@codepoets.co.uk>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
X-GnuPG-Key-URL: http://codepoets.co.uk/files/pubkey.txt
X-PGP-Key: 0x117957A6
User-Agent: Mutt/1.5.13 (2006-08-11)
Content-Length: 136
Lines: 7
hello world; this is in plain text only.
--
David Goodwin
[ http://www.codepoets.co.uk ]

@ -1,110 +0,0 @@
Return-Path: <fw-general-return-20540-david=example.org@lists.zend.com>
X-Original-To: david@example.org
Delivered-To: david@example.org
Received: by mail.palepurple.co.uk (Postfix, from userid 1007)
id A41BE894CF8; Tue, 5 Aug 2008 19:46:09 +0100 (BST)
Received: from localhost (localhost [127.0.0.1])
by mail.palepurple.co.uk (Postfix) with ESMTP id 6786E894CF9
for <david@example.org>; Tue, 5 Aug 2008 19:46:09 +0100 (BST)
X-Virus-Scanned: by Amavis+SpamAssassin+ClamAV and more at palepurple.co.uk
X-Spam-Score: -2.478
X-Spam-Level:
X-Spam-Status: No, score=-2.478 tagged_above=-99 required=5 tests=[AWL=0.545,
BAYES_00=-2.599, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-1,
SPF_HELO_NEUTRAL=0.576, SPF_PASS=-0.001]
Received: from mail.palepurple.co.uk ([127.0.0.50])
by localhost (oak.palepurple.co.uk [127.0.0.50]) (amavisd-new, port 10024)
with ESMTP id F7C1kX6O4LsN for <david@example.org>;
Tue, 5 Aug 2008 19:46:01 +0100 (BST)
Received: from www.zend.com (lists.zend.com [67.15.86.102])
by mail.palepurple.co.uk (Postfix) with SMTP id 83287894CF8
for <david@example.org>; Tue, 5 Aug 2008 19:46:01 +0100 (BST)
Received: (qmail 28760 invoked by uid 505); 5 Aug 2008 18:45:46 -0000
Mailing-List: contact fw-general-help@lists.zend.com; run by ezmlm
Precedence: bulk
List-Post: <mailto:fw-general@lists.zend.com>
List-Help: <mailto:fw-general-help@lists.zend.com>
List-Unsubscribe: <mailto:fw-general-unsubscribe@lists.zend.com>
List-Subscribe: <mailto:fw-general-subscribe@lists.zend.com>
Delivered-To: mailing list fw-general@lists.zend.com
Received: (qmail 28753 invoked from network); 5 Aug 2008 18:45:46 -0000
DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws;
s=s1024; d=yahoo.com;
h=Received:X-Mailer:Date:From:Subject:To:Cc:MIME-Version:Content-Type:Message-ID;
b=RX7cjkrkpdsfHOXg2TRzzF2P5UXe0S5UVRucVl9FdqyE070/mV2za8ehvsGVRTh11tjkhkzh9QJoijpzHTTyu8F4HUHHoql4wUS6zJJC/PgdcCpBVXf0Im4RkyXqhIOAndNk1d9tCPmUnKDjC6SvO6i0Xd5+CqFH9f+eaKzUFAI=;
X-Mailer: YahooMailRC/1042.48 YahooMailWebService/0.7.218
Date: Tue, 5 Aug 2008 11:45:44 -0700 (PDT)
From: =?iso-8859-1?Q?P=E1draic_Brady?= <some.one@yahoo.com>
To: Some one Else <someone.else@gmail.com>
Cc: Zend Framework General <overthere@example.org>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="0-283769398-1217961944=:498"
Message-ID: <944272.498.qm@web55003.mail.re4.yahoo.com>
X-pstn-neptune: 0/0/0.00/0
X-pstn-levels: (S:99.90000/99.90000 CV:99.0000 P:95.9108 M:97.0282 C:98.6951 )
X-pstn-settings: 1 (0.1500:0.1500) cv gt3 gt2 gt1 p m c
X-pstn-addresses: from <some.one@yahoo.com> [638/31]
Subject: Re: [fw-general] Zend_Paginate how to integrate?
Content-Length: 4072
Lines: 60
--0-283769398-1217961944=:498
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable
I do pretty much what Giorgio suggests and tie it into the Model as much as=
possible - fits into the concept of doing as little as possible in your co=
ntrollers by pushing reusable code into Model (or other) objects if appropr=
iate.=0A=0A P=E1draic Brady=0A=0Ahttp://blog.astrumfutura.com=0Ahttp://www.=
patternsforphp.com=0AOpenID Europe Foundation=0A=0A=0A=0A=0A----- Original =
Message ----=0AFrom: Giorgio Sironi <whatever@example.org>=0ATo=
: Axel W=FCstemann <awu@xxxqbus.de>=0ACc: fw-general@xxlists.zend.com=0ASent: Tu=
esday, August 5, 2008 7:20:48 PM=0ASubject: Re: [fw-general] Zend_Paginate =
how to integrate?=0A=0A2008/8/5 Axel W=FCstemann <awuxxxx@qbus.de>:=0A> Yes, it=
seems to me a good idea to let reside the paginator in the model.=0A> What=
happens in the controller? How the view comes into play?=0A=0AThe controll=
er simply calls the method prepareArticles with the right=0Apage (a param o=
f request) and pass the paginator to the view, so the=0Aview script can use=
it for helpers like PaginationControl. Note that=0Abecause the paginator g=
oes into the view, it return only=0Amultidimensional array and not objects.=
=0A=0A-- =0AGiorgio Sironi=0APiccolo Principe & Ossigeno Scripter=0Ahttp://=
www.sourceforge.net/projects/ossigeno=0A
--0-283769398-1217961944=:498
Content-Type: text/html; charset=iso-8859-1
Content-Transfer-Encoding: quoted-printable
<html><head><style type=3D"text/css"><!-- DIV {margin:0px;} --></style></he=
ad><body><div style=3D"font-family:Courier New,courier,monaco,monospace,san=
s-serif;font-size:10pt"><font style=3D"font-family: times new roman,new yor=
k,times,serif;" size=3D"3">I do pretty much what Giorgio suggests and tie i=
t into the Model as much as possible - fits into the concept of doing as li=
ttle as possible in your controllers by pushing reusable code into Model (o=
r other) objects if appropriate.</font><br><div>&nbsp;</div><span style=3D"=
color: rgb(0, 0, 191);"><font style=3D"font-family: times new roman,new yor=
k,times,serif;" size=3D"3"><span style=3D"font-weight: bold;">P=E1draic Bra=
dy<br><br></span></font><span style=3D"font-style: italic;"><font style=3D"=
font-family: times new roman,new york,times,serif;" size=3D"3"><a rel=3D"no=
follow" target=3D"_blank" href=3D"http://blog.astrumfutura.com">http://blog=
.astrumfutura.com</a><br><a rel=3D"nofollow" target=3D"_blank"
href=3D"http://www.patternsforphp.com">http://www.patternsforphp.com</a><b=
r><a rel=3D"nofollow" target=3D"_blank" href=3D"http://www.openideurope.eu/=
">OpenID Europe Foundation</a><br></font></span></span><div><br></div><div =
style=3D"font-family: Courier New,courier,monaco,monospace,sans-serif; font=
-size: 10pt;"><br><div style=3D"font-family: arial,helvetica,sans-serif; fo=
nt-size: 10pt;">----- Original Message ----<br>From: Giorgio Sironi &lt;pic=
coloprincipeazzurroxxxxx@gxxxmail.com&gt;<br>To: Axel W=FCstemann &lt;awuxx@qbus.de&g=
t;<br>Cc: fw-general@xxxlists.zend.com<br>Sent: Tuesday, August 5, 2008 7:20:4=
8 PM<br>Subject: Re: [fw-general] Zend_Paginate how to integrate?<br><br>=
=0A2008/8/5 Axel W=FCstemann &lt;<a ymailto=3D"mailto:awuxxx@xxxqbus.de" href=3D"=
mailto:awuxx@xxqbus.de">xxawu@qxxxbus.de</a>&gt;:<br>&gt; Yes, it seems to me a good=
idea to let reside the paginator in the model.<br>&gt; What happens in the=
controller? How the view comes into play?<br><br>The controller simply cal=
ls the method prepareArticles with the right<br>page (a param of request) a=
nd pass the paginator to the view, so the<br>view script can use it for hel=
pers like PaginationControl. Note that<br>because the paginator goes into t=
he view, it return only<br>multidimensional array and not objects.<br><br>-=
- <br>Giorgio Sironi<br>Piccolo Principe &amp; Ossigeno Scripter<br><a href=
=3D"http://www.sourceforge.net/projects/ossigeno" target=3D"_blank">http://=
www.sourceforge.net/projects/ossigeno</a><br></div></div></div></body></htm=
l>
--0-283769398-1217961944=:498--

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save