-
89.github/workflows/php.yml
-
10.gitignore
-
9.php-cs-fixer.dist.php
-
1.travis.yml
-
45ADDITIONS/README.md
-
22ADDITIONS/fetchmail.pl
-
2ADDITIONS/mailbox_remover.pl
-
2ADDITIONS/postfixadmin-domain-postdeletion.sh
-
2ADDITIONS/postfixadmin-mailbox-postdeletion.sh
-
19ADDITIONS/postfixadmin-mailbox-postpassword.sh
-
10ADDITIONS/quota_usage.pl
-
1ADDITIONS/squirrelmail-plugin/common.php
-
18ADDITIONS/squirrelmail-plugin/functions.inc.php
-
1ADDITIONS/squirrelmail-plugin/postfixadmin_changepass.php
-
2ADDITIONS/squirrelmail-plugin/postfixadmin_vacation.php
-
10ADDITIONS/squirrelmail-plugin/setup.php
-
3ADDITIONS/virtualmaildel.php
-
133CHANGELOG.TXT
-
57DOCUMENTS/DOVECOT.txt
-
21DOCUMENTS/FAQ.txt
-
229DOCUMENTS/HASHING.md
-
56DOCUMENTS/Migration.md
-
37DOCUMENTS/OPENDKIM.txt
-
35DOCUMENTS/POSTFIX_CONF.txt
-
110DOCUMENTS/Password_Expiration.md
-
35DOCUMENTS/Postfix-Dovecot-Postgresql-Example.md
-
48DOCUMENTS/README.password_expiration
-
0DOCUMENTS/Roundcubemail-TOTP-sync.example.sh
-
62DOCUMENTS/SECURITY.txt
-
26DOCUMENTS/SUPERADMIN.txt
-
19DOCUMENTS/UPGRADE.txt
-
82DOCUMENTS/screenshots/README.md
-
2DOCUMENTS/screenshots/README.txt
-
BINDOCUMENTS/screenshots/admin-list.png
-
BINDOCUMENTS/screenshots/admin-login.png
-
BINDOCUMENTS/screenshots/admin-welcome.png
-
BINDOCUMENTS/screenshots/create-new-alias.png
-
BINDOCUMENTS/screenshots/dkim-add-domain-key.png
-
BINDOCUMENTS/screenshots/dkim-add-sign-table-entry.png
-
BINDOCUMENTS/screenshots/domain-audit-log.png
-
BINDOCUMENTS/screenshots/domain-edit.png
-
BINDOCUMENTS/screenshots/domain-list.png
-
BINDOCUMENTS/screenshots/fetchmail-new-config.png
-
BINDOCUMENTS/screenshots/mailbox-adding.png
-
BINDOCUMENTS/screenshots/mailboxes-and-forwards-for-domain.png
-
BINDOCUMENTS/screenshots/postfixadmin-admin-create-alias.jpg
-
BINDOCUMENTS/screenshots/postfixadmin-admin-create-domain.jpg
-
BINDOCUMENTS/screenshots/postfixadmin-admin-create-mailbox.jpg
-
BINDOCUMENTS/screenshots/postfixadmin-admin-domain-list.jpg
-
BINDOCUMENTS/screenshots/postfixadmin-admin-virtual-list.jpg
-
BINDOCUMENTS/screenshots/postfixadmin-inital-welcome.jpg
-
BINDOCUMENTS/screenshots/postfixadmin-mail-admin-login.jpg
-
BINDOCUMENTS/screenshots/postfixadmin-user-change-forward.jpg
-
BINDOCUMENTS/screenshots/postfixadmin-user-overview.jpg
-
BINDOCUMENTS/screenshots/postfixadmin-user-vacation.jpg
-
BINDOCUMENTS/screenshots/setup-step1.png
-
BINDOCUMENTS/screenshots/setup-step2.png
-
BINDOCUMENTS/screenshots/users-edit-mail-forward.png
-
BINDOCUMENTS/screenshots/users-enable-vacation-autoresponse.png
-
BINDOCUMENTS/screenshots/users-forgotten-password.png
-
BINDOCUMENTS/screenshots/users-login.png
-
BINDOCUMENTS/screenshots/users-welcome.png
-
123INSTALL.TXT
-
34README.md
-
23SECURITY.md
-
12VIRTUAL_VACATION/Contributions.txt
-
213VIRTUAL_VACATION/vacation.pl
-
20check_mailpass_expiration.sh
-
51common.php
-
7composer-update.sh
-
42composer.json
-
214config.inc.php
-
9configs/menu.conf
-
2debian/README.Debian
-
236debian/changelog
-
12debian/control
-
16debian/patches/config-debian.diff
-
9debian/postfixadmin.dirs
-
0debian/postfixadmin.docs
-
2debian/postfixadmin.examples
-
8debian/postfixadmin.install
-
1debian/postfixadmin.links
-
10debian/postfixadmin.postinst
-
2debian/postfixadmin.prerm
-
9debian/rules
-
4debian/upstream/metadata
-
4debian/watch
-
950functions.inc.php
-
62install.sh
-
101languages/bg.lang
-
101languages/ca.lang
-
102languages/cn.lang
-
143languages/cs.lang
-
102languages/da.lang
-
116languages/de.lang
-
115languages/en.lang
-
102languages/es.lang
-
104languages/et.lang
-
102languages/eu.lang
-
100languages/fi.lang
@ -1,7 +1,15 @@ |
|||
/config.local.php |
|||
/templates_c/*.tpl.php |
|||
/templates_c/*menu.conf.php |
|||
/vendor/ |
|||
/.php_cs.cache |
|||
/.idea |
|||
/vendor |
|||
/composer.lock |
|||
/coverage |
|||
/composer.phar |
|||
/composer_2.phar |
|||
/.php-cs-fixer.cache |
|||
/.phpunit.result.cache |
|||
/build |
|||
/tests/postfixadmin.sqlite.*.test |
|||
/phpstorm-docker-dev/ |
|||
@ -1,52 +1,69 @@ |
|||
# |
|||
# Postfix Admin ADDITIONS |
|||
# |
|||
|
|||
BEFORE YOU START |
|||
---------------- |
|||
# BEFORE YOU START |
|||
|
|||
|
|||
**** ALL THESE SCRIPTS ARE CREATED BY THIRD PARTIES **** |
|||
**** THEY ARE AS IS, USE AT YOUR OWN RISK! **** |
|||
|
|||
ADDITIONS |
|||
--------- |
|||
# ADDITIONS |
|||
|
|||
In this directory you will find additional scripts that are build by others. |
|||
|
|||
- change_password.tgz |
|||
## change_password.tgz |
|||
|
|||
by George Vieira <george at citadelcomputer dot com dot au> |
|||
SquirrelMail plugin to change your passwor |
|||
|
|||
- cleanupdirs.pl |
|||
## cleanupdirs.pl |
|||
|
|||
by jared bell <jared at beol dot net> |
|||
Displays a list of mailboxes that need to be deleted |
|||
|
|||
- mailbox_remover.pl |
|||
## mailbox_remover.pl |
|||
|
|||
by Petr Znojemsky |
|||
Deletes all unused mailboxes |
|||
|
|||
- mkeveryone.pl |
|||
## mkeveryone.pl |
|||
|
|||
by Joshua Preston |
|||
Generate an 'everybody' alias for a domain. |
|||
|
|||
- pfa_maildir_cleanup.pl |
|||
## pfa_maildir_cleanup.pl |
|||
by Stephen Fulton <sfulton at esoteric dot ca> |
|||
Deletes all unused mailboxes |
|||
|
|||
- postfixadmin-0.3-1.4.tar.gz |
|||
## 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 |
|||
See also : https://github.com/postfixadmin/postfixadmin/tree/master/ADDITIONS/squirrelmail-plugin |
|||
|
|||
|
|||
## virtualmaildel.php |
|||
|
|||
by George Vieira <george at citadelcomputer dot com dot au> |
|||
Deletes all unused mailboxes |
|||
|
|||
## Example mailbox / domain scripts for Postfixadmin |
|||
|
|||
- 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. |
|||
|
|||
|
|||
## Cyrus Quota Usage |
|||
|
|||
See https://github.com/o-m-d/cyrus-quotausage-to-pfa |
|||
|
|||
@ -0,0 +1,19 @@ |
|||
#!/bin/bash |
|||
|
|||
# Example script for dovecot mail-crypt-plugin |
|||
# https://doc.dovecot.org/configuration_manual/mail_crypt_plugin/ |
|||
|
|||
IFS= read -r -d $'\0' OLD_PASSWORD |
|||
IFS= read -r -d $'\0' NEW_PASSWORD |
|||
|
|||
# New user |
|||
if [ -z "$OLD_PASSWORD" ]; then |
|||
OLD_PASSWORD="$(openssl rand -hex 16)" |
|||
doveadm -o plugin/mail_crypt_private_password="$OLD_PASSWORD" mailbox cryptokey generate -u "$1" -U |
|||
fi |
|||
|
|||
# If you're using dovecot >= 2.3.19, try this instead (See: https://github.com/postfixadmin/postfixadmin/issues/646) |
|||
# printf "%s\n%s\n" "$OLD_PASSWORD" "$NEW_PASSWORD" "$NEW_PASSWORD" | doveadm mailbox cryptokey password -u "$1" -N -O |
|||
|
|||
# Password change |
|||
printf "%s\n%s\n" "$OLD_PASSWORD" "$NEW_PASSWORD" | doveadm mailbox cryptokey password -u "$1" -N -O "" |
|||
@ -0,0 +1,229 @@ |
|||
# PostfixAdmin Password Hash Support. |
|||
|
|||
How are your passwords stored in the database. |
|||
|
|||
They should not be stored in plain text. |
|||
|
|||
Whatever format you choose will need to be supported by your IMAP server (and whatever provides SASL auth for Postfix) |
|||
|
|||
If you can, use a format that includes a different salt per password (e.g. one of the crypt variants, like Blowfish (BLF-CRYPT) or Argon2I/Argon2ID). |
|||
Try and avoid formats that are unsalted hashes (md5, SHA1) as these offer minimal protection in the event of a data leak. |
|||
|
|||
## Configuration |
|||
|
|||
See config.inc.php (or config.local.php) and look for |
|||
|
|||
```php |
|||
$CONF['encrypt'] = 'something'; |
|||
``` |
|||
|
|||
## Supported Formats |
|||
|
|||
This document is probably not complete. |
|||
|
|||
It possibly provides better documentation than was present before. This may not say much. |
|||
|
|||
Supported hash formats include : |
|||
|
|||
* MD5-CRYPT (aka MD5), |
|||
* SHA1, |
|||
* SHA1-CRYPT, |
|||
* SSHA (4 char salted sha1), |
|||
* BLF-CRYPT (Blowfish), |
|||
* SHA512, |
|||
* SHA512-CRYPT, |
|||
* ARGON2I, |
|||
* ARGON2ID, |
|||
* SHA256, |
|||
* SHA256-CRYPT, |
|||
* PLAIN-MD5 (aka md5) |
|||
* CRYPT |
|||
|
|||
Historically PostfixAdmin has supported all dovecot algorithms (methods) by using the 'doveadm' system binary. As of early 2023 (?), we attempted to use a native/PHP implementation for a number of these to remove issues caused by use of proc_open / dovecot file permissions etc (see e.g. #379). |
|||
|
|||
It's recommended you use the algorithm/mechanism from your MTA, and configure PostfixAdmin with the same value prefixed by the MTA name - |
|||
|
|||
For example, if dovecot has `default_pass_scheme = SHA256` use `$CONF['encrypt'] = 'SHA256'; ` in PostfixAdmin. |
|||
|
|||
|
|||
| Dovecot pass scheme | PostfixAdmin `$CONF['encrypt']` setting | |
|||
|---------------------|-----------------------------------------| |
|||
| SHA256 | SHA256 | |
|||
| SHA256-CRYPT.B64 | SHA256-CRYPT.B64 | |
|||
| SHA256-CRYPT | SHA256-CRYPT | |
|||
| SHA512-CRYPT | SHA512-CRYPT | |
|||
| ARGON2I | ARGON2I | |
|||
| ARGON2ID | ARGON2ID | |
|||
|
|||
|
|||
|
|||
| Courier Example | PostfixAdmin | |
|||
|-----------------|--------------| |
|||
| md5 | courier:md5 | |
|||
| md5raw | courier:md5raw | |
|||
| sha1 | courier:sha1 | |
|||
| ssha | courier:ssha | |
|||
| sha256 | courier:sha256 | |
|||
|
|||
|
|||
### cleartext |
|||
|
|||
No hashing. May be useful for debugging. |
|||
|
|||
Insecure. Try to avoid. May be useful for legacy purposes. |
|||
|
|||
### mysql_encrypt |
|||
|
|||
Uses the MYSQL ENCRYPT() function (this uses 'crypt' underneath). |
|||
|
|||
Can be secure. |
|||
|
|||
Requires MySQL. |
|||
|
|||
Should use a sha512 salt for new values. |
|||
|
|||
### md5crypt |
|||
|
|||
md5crypt = uses md5crypt() function - in a 'crypt' like format. |
|||
|
|||
e.g. |
|||
|
|||
`$1$c9809462$M0zeLuOvixH61C2csGN.U0` |
|||
|
|||
You should not use this for new installations |
|||
|
|||
(it probably does not offer a high level of security) |
|||
|
|||
### md5 |
|||
|
|||
PHP's md5() function. |
|||
|
|||
You should not use this (it does not offer a high level of security), but is probably better than cleartext. |
|||
|
|||
### system |
|||
|
|||
Uses PHP's crypt function. |
|||
|
|||
Probably throws an E_NOTICE. |
|||
|
|||
Example : `$1$tWgqTIuF$1HFciCXrhVpACGjBMxNr/0` |
|||
|
|||
### authlib |
|||
|
|||
See source code. Presumably useful for Courier based installations. |
|||
|
|||
#### With `$CONF['authlib_default_flavor'] = 'md5raw`;` |
|||
|
|||
might give something like : |
|||
|
|||
`{md5raw}3858f62230ac3c915f300c664312c63f` |
|||
|
|||
Based on md5, so avoid. |
|||
|
|||
#### With `$CONF['authlib_default_flavor'] = 'crypt`;` |
|||
|
|||
Uses PHP Crypt. |
|||
|
|||
`{crypt}blfqitzeBpyAE` |
|||
|
|||
Presumably weak. |
|||
|
|||
#### With `$CONF['authlib_default_flavor'] = 'SHA';` |
|||
|
|||
Uses sha1, base64 encoded. Unsalted. Avoid. |
|||
|
|||
### dovecot:METHOD |
|||
|
|||
May use dovecot binary to produce hash, if the format you request isn't in PFACrypt::DOVECOT_NATIVE |
|||
|
|||
Using a format that PostfixAdmin doesn't support natively has the following pros/cons : |
|||
|
|||
#### Pros |
|||
|
|||
* Minimal dependency on PostfixAdmin / PHP code. |
|||
* Hash should definitely work with dovecot! |
|||
|
|||
#### Cons |
|||
|
|||
* file permissions and/or execution of doveadm by the web server may be problematic. |
|||
* requires: proc_open(...) - which might be blocked by e.g. safemode. |
|||
* doveadm may not be installed. |
|||
* possible issues with SELinux |
|||
* See https://github.com/postfixadmin/postfixadmin/issues/398 (file permissions) |
|||
|
|||
#### Incomplete list of CRYPT-METHOD |
|||
|
|||
* CRAM-MD5 |
|||
* SHA |
|||
* SHA1 |
|||
* SHA256 |
|||
* SHA512 |
|||
* CLEAR |
|||
* CLEARTEXT |
|||
* PLAIN |
|||
* PLAIN-TRUNC |
|||
|
|||
If in doubt, try `dovecot:SHA512` |
|||
|
|||
Dovecot generated passwords in your database should look a bit like : |
|||
|
|||
`{SHA256}JMQi5oHxwb0IKGx6r10jpfCI3NsLIZgGs6nleSRPAMU=` |
|||
|
|||
If you have problems, start by checking you can generate one on the command line using e.g |
|||
|
|||
`doveadm pw -s SHA256` |
|||
|
|||
### php_crypt |
|||
|
|||
Potentially the most secure. |
|||
|
|||
By default it will generate a SHA512 salt. Output in crypt format. |
|||
|
|||
Other methods : |
|||
|
|||
* BLOWFISH |
|||
* SHA512 |
|||
* SHA256 |
|||
* DES (avoid) |
|||
* MD5 (avoid) |
|||
|
|||
e.g. |
|||
|
|||
`$6$emcsNNrzGZSN64mI$A/bmacTGSp2UrdcPvaROrR2FPQS5KlnoU.a/0zmfpaubBO9o1ZcgyQIic4Qb59SMxA2H8YxgS1XILO1wZhjkZ0` |
|||
|
|||
You can specify the salting method using a :METHOD in the specification. |
|||
|
|||
e.g. |
|||
|
|||
`$CONF['encrypt'] = 'php_crypt:SHA512';` |
|||
|
|||
You can make the hashing more 'difficult' by specifying an additional parameter like : |
|||
|
|||
`$CONF['encrypt'] = 'php_crypt:SHA512:5000';` |
|||
|
|||
which should change the 'cost' (BLOWFISH) or rounds (SHA256, SHA512). |
|||
|
|||
finally you can ask that the generated hash has a specific prefix (e.g. {SHA512} ) like : |
|||
|
|||
`$CONF['encrypt'] = 'php_crypt:SHA512:5000:{SHA512-CRYPT}';` |
|||
|
|||
### sha512.b64 |
|||
|
|||
See https://github.com/postfixadmin/postfixadmin/issues/58 |
|||
|
|||
No dovecot dependency; should support migration from md5crypt |
|||
|
|||
Output is base64 encoded i.e. a hash like : |
|||
|
|||
* `$6$emcsNNrzGZSN64mI$A/bmacTGSp2UrdcPvaROrR2FPQS5KlnoU.a/0zmfpaubBO9o1ZcgyQIic4Qb59SMxA2H8YxgS1XILO1wZhjkZ0` |
|||
|
|||
is base64 encoded into : |
|||
|
|||
* JDYkZW1jc05OcnpHWlNONjRtSSRBL2JtY... |
|||
|
|||
and then formatted to become : |
|||
|
|||
* {SHA512-CRYPT.B64}JDYkZW1jc05OcnpHWlNONjRtSSRBL2JtY.... |
|||
|
|||
This format should support older passwords with a {MD5-CRYPT} prefix, to allow you to migrate. |
|||
|
|||
@ -0,0 +1,56 @@ |
|||
# Migrating to Postfixadmin from other products |
|||
|
|||
## From Postfix |
|||
|
|||
Where a database structure like this exists : |
|||
|
|||
See also: https://github.com/postfixadmin/postfixadmin/issues/468 |
|||
|
|||
|
|||
```SQL |
|||
|
|||
CREATE TABLE `virtual_domains` ( |
|||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|||
`name` varchar(50) CHARACTER SET latin1 NOT NULL, |
|||
PRIMARY KEY (`id`) |
|||
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; |
|||
|
|||
CREATE TABLE `virtual_aliases` ( |
|||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|||
`domain_id` int(11) NOT NULL, |
|||
`source` varchar(40) CHARACTER SET latin1 NOT NULL, |
|||
`destination` varchar(80) CHARACTER SET latin1 NOT NULL, |
|||
PRIMARY KEY (`id`), |
|||
KEY `domain_id` (`domain_id`), |
|||
CONSTRAINT `virtual_aliases_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `virtual_domains` (`id`) ON DELETE CASCADE |
|||
) ENGINE=InnoDB AUTO_INCREMENT=465 DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; |
|||
|
|||
CREATE TABLE `virtual_users` ( |
|||
`id` int(11) NOT NULL AUTO_INCREMENT, |
|||
`domain_id` int(11) NOT NULL, |
|||
`user` varchar(40) CHARACTER SET latin1 NOT NULL, |
|||
`password` varchar(32) CHARACTER SET latin1 NOT NULL, |
|||
PRIMARY KEY (`id`), |
|||
UNIQUE KEY `UNIQUE_EMAIL` (`domain_id`,`user`), |
|||
CONSTRAINT `virtual_users_ibfk_1` FOREIGN KEY (`domain_id`) REFERENCES `virtual_domains` (`id`) ON DELETE CASCADE |
|||
) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=latin1 COLLATE=latin1_german1_ci; |
|||
|
|||
``` |
|||
|
|||
## Possible route |
|||
|
|||
You'll need to modify the below to match how your mailboxes are stored on disk (the maildir). |
|||
|
|||
It assumes the password hash format is compatible. If not some sort of blanket reset is probably required. |
|||
|
|||
### Migrate domains |
|||
|
|||
`insert into domain (domain, description, transport) select name, name, 'virtual' from postfix_legacy.virtual_domains;` |
|||
|
|||
### Migrate users |
|||
|
|||
` insert into mailbox (username, password, name, maildir, local_part, domain) select concat(user, '@', d.name), password, user, concat(d.name, '/', user), user, d.name FROM postfix_legacy.virtual_users INNER JOIN postfix_legacy.virtual_domains d ON postfix_legacy.virtual_users.domain_id = d.id;` |
|||
|
|||
### Migrate Aliases |
|||
|
|||
`insert into alias (address, goto, domain) select concat(a.source, '@', d.name), a.destination, d.name FROM postfix_legacy.virtual_aliases a INNER JOIN postfix_legacy.virtual_domains d ON d.id = a.domain_id;` |
|||
@ -0,0 +1,37 @@ |
|||
# |
|||
# OpenDKIM configuration for Postfix Admin |
|||
# Originally written by: Fredrik <Freddo> Falk |
|||
# |
|||
|
|||
More complete OpenDKIM documentation: |
|||
|
|||
http://www.opendkim.org/opendkim.8.html |
|||
http://www.opendkim.org/opendkim.conf.5.html |
|||
http://www.opendkim.org/opendkim-genkey.8.html |
|||
https://github.com/trusteddomainproject/OpenDKIM/blob/master/opendkim/README.SQL |
|||
|
|||
Here are the relevant parts of OpenDKIM v2.11.x configuration for Postfixadmin setup. |
|||
|
|||
Please refer to OpenDKIM documentation for complete information. |
|||
|
|||
The setup gets KeyTable and SigningTable info from MySQL, allowing domain admins to edit and add domain keys as well as |
|||
assign which authors will use them. |
|||
|
|||
|
|||
1. PostfixAdmin Setup |
|||
----------------- |
|||
|
|||
Add `$CONF['dkim'] = 'YES';` to your `config.local.php`, and optionally ``$CONF['dkim_all_admins'] = 'YES';` to allow |
|||
non-super-admins to add domain keys and signtable entries. |
|||
|
|||
|
|||
2. OpenDKIM setup |
|||
----------------- |
|||
|
|||
Ensure that the version of OpenDKIM supports databases/OpenDBX. |
|||
After that, simply add the following to your /etc/opendkim.conf: |
|||
``` |
|||
SigningTable dsn:mysql://{USER}:{PASSWORD}@{HOST}/{DATABASE}/table=dkim_signing?keycol=author?datacol=dkim_id |
|||
KeyTable dsn:mysql://{USER}:{PASSWORD}@{HOST}/{DATABASE}/table=dkim?keycol=id?datacol=domain_name,selector,private_key |
|||
``` |
|||
Replace {USER}, {PASSWORD}, {HOST}, and {DATABASE} with your values. |
|||
@ -0,0 +1,110 @@ |
|||
# 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 |
|||
|
|||
Password Expiration is merged with PostfixAdmin - so no additional database changes should be necessary. |
|||
|
|||
|
|||
## Database Fields |
|||
|
|||
* mailbox.password_expiry - timestamp, when the mailbox password expires. |
|||
* domain.password_expiry - default duration for when a password will expire |
|||
|
|||
Changes in MySQL/MariaDB mailbox table (as defined in `$CONF['database_tables']` from config.inc.php): |
|||
|
|||
## Changes in Postfix Admin : |
|||
|
|||
To enable password expiration, add the following to your config.inc.php file: |
|||
|
|||
`$CONF['password_expiration'] = 'YES';` |
|||
|
|||
## RoundCube Password Plugin |
|||
|
|||
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 course, you may adapt to the expiration value to suit. |
|||
|
|||
|
|||
## Changes in Dovecot (adapt if you use another LDA) |
|||
|
|||
Edit dovecot-mysql.conf file, and replace the user_query (and only this one) to be based on 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. An example is given below. |
|||
|
|||
Edit the script to adapt the variables to your setup. |
|||
|
|||
This script is using `postfixadmin.my.cnf` to read credentials, which might look a bit like : |
|||
|
|||
```ini |
|||
[client] |
|||
user = me |
|||
password = secret |
|||
host = hostname |
|||
``` |
|||
|
|||
Edit this file to enter a DB user that is allowed to access (read only) your database. |
|||
|
|||
You could create a new MySQL user with only SELECT permission on mailbox.username and mailbox.password_expiry. |
|||
|
|||
This file should be protected from other users (e.g. chmod 400). |
|||
|
|||
### Expiration Script |
|||
|
|||
```bash |
|||
#!/bin/bash |
|||
|
|||
# Adapt to your setup |
|||
|
|||
# Be careful who you run this script as; other system users may be able to write to the postfixadmin database, inject |
|||
# malicious data into e.g. mailbox.username and then be able to execute commands as the user running this script. |
|||
|
|||
# So, please try to avoid running this script as root. |
|||
|
|||
POSTFIX_DB="postfixadmin" |
|||
MYSQL_CREDENTIALS_FILE="postfixadmin.my.cnf" |
|||
|
|||
REPLY_ADDRESS="noreply@example.com" |
|||
|
|||
# Change this list to change notification times and when ... |
|||
for INTERVAL in 30 14 7 |
|||
do |
|||
LOWER=$(( $INTERVAL - 1 )) |
|||
|
|||
QUERY="SELECT username,password_expiry FROM mailbox WHERE password_expiry > now() + interval $LOWER DAY AND password_expiry < NOW() + interval $INTERVAL DAY" |
|||
|
|||
mysql --defaults-extra-file="$MYSQL_CREDENTIALS_FILE" "$POSTFIX_DB" -B -N -e "$QUERY" | while IFS=$'\t' read -a RESULT ; do |
|||
|
|||
EMAIL_TO=${RESULT[0]} |
|||
PASSWORD_EXPIRE=${RESULT[1]} |
|||
|
|||
# basic attempt at validating email address looks legit. |
|||
if [[ "$EMAIL_TO" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$ ]] |
|||
then |
|||
echo -e "Dear User, \n Your password will expire on ${PASSWORD_EXPIRE}" | mail -s "Password $INTERVAL days before expiration notification" -r $REPLY_ADDRESS "${EMAIL_TO}" |
|||
fi |
|||
done |
|||
done |
|||
|
|||
``` |
|||
@ -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,16 +1,20 @@ |
|||
------------------------------------ |
|||
Recreating a superadmin account |
|||
# Recreating a superadmin account |
|||
|
|||
Login to setup.php using the setup_password you have setup config.local.php to contain. |
|||
|
|||
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!. |
|||
From setup.php you can add a 'superadmin' account. This account can access any domain or mailboxes defined within Postfixadmin. |
|||
|
|||
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. |
|||
The 'superadmin' account is able to create additional 'admin' users which have their access restricted to domains of your choice. |
|||
|
|||
In case you forgot your superadmin username or password, you can create a new |
|||
superadmin account using setup.php. |
|||
## Forgotten setup_password |
|||
|
|||
If you also have forgotten your setup password, you can use setup.php to configure |
|||
a new setup password. |
|||
In case you forgot your superadmin username or password, you can create a new superadmin account using setup.php. |
|||
|
|||
## Forgotten superadmin username(s) |
|||
|
|||
Once you have authenticated with your setup_password on setup.php, a list of superadmin usernames is printed out. |
|||
|
|||
## Forgotten superadmin password |
|||
|
|||
The easiest approach is to create a new superadmin user, and then using a database tool of your choice update the old |
|||
user with the password hash to have the password hash of a new user. |
|||
@ -0,0 +1,82 @@ |
|||
# Some screenshots of Postfixadmin |
|||
|
|||
## 1. Setup process |
|||
|
|||
When you visit visit https://your-site.com/postfixadmin/setup.php you'll see this - |
|||
|
|||
 |
|||
|
|||
After creating and adding the setup password hash into your config file, and then logging into the setup page with that password, you should see : |
|||
|
|||
 |
|||
|
|||
If there are any hosting errors, or issues with your environment, they may be listed here. |
|||
|
|||
Create a new admin account using your setup password .... then you can login as an admin and start creating domains and mailboxes. |
|||
|
|||
## 2. As an Admin user |
|||
|
|||
### Login |
|||
|
|||
 |
|||
|
|||
### Welcome page |
|||
|
|||
 |
|||
|
|||
### View other admins |
|||
|
|||
 |
|||
|
|||
|
|||
### View mailboxes and aliases for domain |
|||
|
|||
 |
|||
|
|||
### Add mailbox |
|||
|
|||
You can create as many mailboxes as you want ... |
|||
|
|||
 |
|||
|
|||
|
|||
### Add aliases (forwards) |
|||
|
|||
 |
|||
|
|||
### Add Fetchmail config for mailbox |
|||
|
|||
 |
|||
|
|||
### Add a Domain Key for use with OpenDKIM |
|||
|
|||
 |
|||
|
|||
### Add a Sign Table Entry for use with OpenDKIM |
|||
|
|||
 |
|||
|
|||
|
|||
## 3. As a User |
|||
|
|||
### Login |
|||
|
|||
 |
|||
|
|||
### Welcome page |
|||
|
|||
|
|||
 |
|||
|
|||
### Change your mail forward |
|||
|
|||
 |
|||
|
|||
### Set / Unset autoresponse (Vacation) |
|||
|
|||
 |
|||
|
|||
### I forgot my password |
|||
|
|||
|
|||
 |
|||
@ -1,2 +0,0 @@ |
|||
Random Screenshots taken on 2007/09/25, using a version of Postfixadmin from subversion. |
|||
|
|||
|
After Width: 2031 | Height: 2092 | Size: 217 KiB |
|
After Width: 2028 | Height: 1837 | Size: 170 KiB |
|
After Width: 2028 | Height: 1837 | Size: 222 KiB |
|
After Width: 2031 | Height: 2092 | Size: 186 KiB |
|
After Width: 1919 | Height: 891 | Size: 149 KiB |
|
After Width: 1919 | Height: 830 | Size: 47 KiB |
|
After Width: 2031 | Height: 2092 | Size: 332 KiB |
|
After Width: 2031 | Height: 2092 | Size: 217 KiB |
|
After Width: 2028 | Height: 1837 | Size: 211 KiB |
|
After Width: 2031 | Height: 2092 | Size: 218 KiB |
|
After Width: 2031 | Height: 2092 | Size: 227 KiB |
|
After Width: 2031 | Height: 2092 | Size: 316 KiB |
|
Before Width: 791 | Height: 351 | Size: 66 KiB |
|
Before Width: 754 | Height: 447 | Size: 67 KiB |
|
Before Width: 790 | Height: 481 | Size: 79 KiB |
|
Before Width: 791 | Height: 351 | Size: 75 KiB |
|
Before Width: 791 | Height: 351 | Size: 92 KiB |
|
Before Width: 760 | Height: 686 | Size: 142 KiB |
|
Before Width: 754 | Height: 447 | Size: 45 KiB |
|
Before Width: 762 | Height: 508 | Size: 86 KiB |
|
Before Width: 790 | Height: 481 | Size: 80 KiB |
|
Before Width: 762 | Height: 508 | Size: 91 KiB |
|
After Width: 2031 | Height: 2092 | Size: 350 KiB |
|
After Width: 2031 | Height: 2092 | Size: 451 KiB |
|
After Width: 1792 | Height: 1675 | Size: 188 KiB |
|
After Width: 1792 | Height: 1675 | Size: 208 KiB |
|
After Width: 1792 | Height: 1675 | Size: 138 KiB |
|
After Width: 1792 | Height: 1675 | Size: 162 KiB |
|
After Width: 1792 | Height: 1675 | Size: 171 KiB |
@ -0,0 +1,23 @@ |
|||
# Security Policy |
|||
|
|||
## Supported Versions |
|||
|
|||
As of 2021/08 - |
|||
|
|||
| Version | Supported | |
|||
| ------- | ------------------ | |
|||
| 'dev' | :x: GitHub 'master' branch, use at own risk! | |
|||
| 3.3.x | :white_check_mark: | |
|||
| 3.2.x | Security/critical fixes only | |
|||
| < 3.2.x | :x: | |
|||
|
|||
Releases are published at : |
|||
|
|||
* https://github.com/postfixadmin/postfixadmin/releases |
|||
* ocassionally at https://sourceforge.net/projects/postfixadmin/ - sometimes with RPM/DEB packages. |
|||
|
|||
## Reporting a Vulnerability |
|||
|
|||
Either message GingerDog or cboltz on the PostfixAdmin libera chat - IRC channel, or email. Email addresses can be found in the 'git' changelog. |
|||
|
|||
|
|||
@ -1,20 +0,0 @@ |
|||
#!/bin/bash |
|||
#Adapt to your setup |
|||
|
|||
POSTFIX_DB="postfix_test" |
|||
MYSQL_CREDENTIALS_FILE="postfixadmin.my.cnf" |
|||
|
|||
REPLY_ADDRESS=noreply@example.com |
|||
|
|||
# Change this list to change notification times and when ... |
|||
for INTERVAL in 30 14 7 |
|||
do |
|||
LOWER=$(( $INTERVAL - 1 )) |
|||
|
|||
QUERY="SELECT username,password_expiry FROM mailbox WHERE password_expiry > now() + interval $LOWER DAY AND password_expiry < NOW() + interval $INTERVAL DAY" |
|||
|
|||
mysql --defaults-extra-file="$MYSQL_CREDENTIALS_FILE" "$POSTFIX_DB" -B -e "$QUERY" | while read -a RESULT ; do |
|||
echo -e "Dear User, \n Your password will expire on ${RESULT[1]}" | mail -s "Password 30 days before expiration notication" -r $REPLY_ADDRESS ${RESULT[0]} |
|||
done |
|||
|
|||
done |
|||
@ -0,0 +1,7 @@ |
|||
#!/bin/bash |
|||
|
|||
# for github : |
|||
composer update --no-dev |
|||
|
|||
# for local testing/dev: |
|||
# composer update |
|||
@ -1,8 +1,7 @@ |
|||
usr/bin |
|||
usr/share/postfixadmin |
|||
usr/share/postfixadmin/scripts |
|||
usr/share/postfixadmin/public |
|||
usr/share/postfixadmin/lib |
|||
#usr/share/postfixadmin/css |
|||
usr/share/doc/postfixadmin |
|||
var/cache/postfixadmin |
|||
usr/bin |
|||
etc/postfixadmin |
|||
etc/apache2/conf-available |
|||
var/cache/postfixadmin/templates_c |
|||
@ -1,9 +1,11 @@ |
|||
*.php usr/share/postfixadmin |
|||
public usr/share/postfixadmin |
|||
configs usr/share/postfixadmin |
|||
languages usr/share/postfixadmin |
|||
lib usr/share/postfixadmin |
|||
model usr/share/postfixadmin |
|||
templates usr/share/postfixadmin |
|||
lib usr/share/postfixadmin |
|||
configs usr/share/postfixadmin |
|||
scripts usr/share/postfixadmin |
|||
templates usr/share/postfixadmin |
|||
configs usr/share/postfixadmin |
|||
debian/lighttpd/90-postfixadmin.conf etc/lighttpd/conf-available |
|||
debian/apache/postfixadmin.conf etc/apache2/conf-available |
|||
@ -1,2 +1 @@ |
|||
etc/postfixadmin/config.inc.php usr/share/postfixadmin/config.inc.php |
|||
var/cache/postfixadmin usr/share/postfixadmin/templates_c |
|||
@ -0,0 +1,4 @@ |
|||
Bug-Database: https://github.com/postfixadmin/postfixadmin/issues |
|||
Bug-Submit: https://github.com/postfixadmin/postfixadmin/issues/new |
|||
Repository: https://github.com/postfixadmin/postfixadmin.git |
|||
Repository-Browse: https://github.com/postfixadmin/postfixadmin |
|||
@ -1,2 +1,2 @@ |
|||
version=3 |
|||
http://sf.net/postfixadmin/postfixadmin-([\d\.]+)\.tar\.gz |
|||
version=4 |
|||
https://github.com/postfixadmin/postfixadmin/releases .*/postfixadmin-(\d[\d.]*)\.tar\.gz |
|||
950
functions.inc.php
File diff suppressed because it is too large
View File
@ -0,0 +1,62 @@ |
|||
#!/bin/bash |
|||
|
|||
set -eu |
|||
|
|||
# PostfixAdmin install script. |
|||
# 1. Downloads 'composer.phar' to the current directory. |
|||
# 2. Runs 'php composer.phar install' which should install required runtime libraries for Postfixadmin |
|||
# 3. Runs 'mkdir templates_c && chmod 777 templates_c' |
|||
|
|||
PATH=/bin:/usr/bin:/usr/local/bin |
|||
export PATH |
|||
|
|||
COMPOSER_URL=https://getcomposer.org/download/latest-stable/composer.phar |
|||
|
|||
type php >/dev/null 2>&1 || { echo >&2 "I require php but it's not installed. Aborting."; exit 1; } |
|||
|
|||
cd "$(dirname "$0")" |
|||
|
|||
# Check for $(pwd)/composer.phar |
|||
|
|||
echo " * Checking for composer.phar " |
|||
|
|||
if [ ! -f composer.phar ]; then |
|||
|
|||
echo " * Trying to download composer.phar from $COMPOSER_URL " |
|||
# try and download it one way or another |
|||
if [ -x /usr/bin/wget ]; then |
|||
wget -q -O composer.phar $COMPOSER_URL |
|||
else |
|||
if [ -x /usr/bin/curl ]; then |
|||
curl -o composer.phar $COMPOSER_URL |
|||
else |
|||
echo " ** Could not find wget or curl; please download $COMPOSER_URL to pwd" >/dev/stderr |
|||
exit 1 |
|||
fi |
|||
fi |
|||
fi |
|||
|
|||
echo " * Running composer install --no-dev" |
|||
|
|||
php composer.phar install --prefer-dist -n --no-dev |
|||
|
|||
|
|||
if [ ! -d templates_c ]; then |
|||
|
|||
|
|||
mkdir -p templates_c && chmod 777 templates_c |
|||
|
|||
echo |
|||
echo " Warning: " |
|||
echo " templates_c directory didn't exist, now created." |
|||
echo |
|||
echo " You should change the ownership and reduce permissions on templates_c to 750. " |
|||
echo " The ownership needs to match the user used to execute PHP scripts, perhaps 'www-data' or 'httpd'" |
|||
echo |
|||
echo " e.g. chown www-data templates_c && chmod 750 templates_c" |
|||
echo |
|||
fi |
|||
echo |
|||
echo "Please continue configuration / setup within your web browser. " |
|||
echo "See also : https://github.com/postfixadmin/postfixadmin/blob/master/INSTALL.TXT#L58 " |
|||
echo |
|||