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:
@ -9,15 +11,12 @@ 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 the last line in the script and replace 90 by the required value.
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_enabled'] = 'YES';
Do not forget to set the expiration value (in days)
$CONF['password_expiration_value'] = '90';
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.
@ -29,8 +28,9 @@ 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:
user_query = SELECT concat('/var/vmail/', maildir) as home, concat('maildir:/var/vmail/', maildir) as mail, 20001 AS uid, 20001 AS gid, concat('dirsize:storage=', quota) AS quota FROM mailbox WHERE username = '%u' AND active = '1' AND pw_expires_on > now()
if course you may require to adapt the uid, gid, maildir and table to your setup
user_query = SELECT concat('/var/vmail/', m.maildir) as home, concat('maildir:/var/vmail/', m.maildir) as mail, 20001 AS uid, 20001 AS gid, concat('dirsize:storage=', m.quota) AS quota, m.domain FROM mailbox m ,domain d WHERE d.domain = m.domain and m.username = 'tutu@eyetech-software.com' AND m.active = '1' and (m.pw_expires_on > now() or d.password_expiration_value = 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).
$PALANG['pCreate_mailbox_result_error'] = 'Creating the mailbox %s failed!';
$PALANG['pCreate_mailbox_result_success'] = 'The mailbox %s has been added to the mailbox table.';
$PALANG['pCreate_mailbox_result_succes_nosubfolders'] = 'The mailbox %s has been added to the mailbox table, but none (or only some) of the predefined sub-folders could be created.';
$PALANG['mailbox_updated'] = "The mailbox %s has been updated.";
$PALANG['mailbox_updated'] = "The mailbox %s has been updated.";
$PALANG['mailbox_update_failed'] = "Updating the mailbox %s failed!";
$PALANG['pEdit_mailbox_welcome'] = 'Edit a mailbox for your domain.';
$PALANG['pPassword_result_error'] = 'Changing the password for %s failed!';
$PALANG['pPassword_result_success'] = 'The password for %s has been changed.';
$PALANG['pPassword_recovery_title'] = 'Follow the instructions to reset your password.';
$PALANG['pPassword_recovery_button'] = 'Send me the code';
$PALANG['pPassword_recovery_email_body'] = "Hello,\n\nUse the following link to change your email password :\n%s\n\nRegards,\n\n" . $CONF['admin_name'];
$PALANG['pPassword_recovery_sms_body'] = "Hello,\nThe code to change your password is: %s\n" . $CONF['admin_name'];
$PALANG['pPassword_recovery_processed'] = "We processed your request. If you entered a valid username, you'll receive an email/SMS with a password code.";
$PALANG['pPassword_password_code'] = 'Code sent by email/SMS';
$PALANG['save'] = 'Enregistrer les modifications';
$PALANG['confirm'] = 'Êtes-vous sûr de vouloir supprimer cet enregistrement\n';
$PALANG['confirm_delete_admin'] = 'Êtes-vous sûr de vouloir supprimer l\'administrateur %s?';
$PALANG['confirm_delete_alias'] = 'Êtes-vous sûr de vouloir supprimer l\'alias %s?';
$PALANG['confirm_delete_aliasdomain'] = 'Êtes-vous sûr de vouloir supprimer l\'alias de domaine %s?';
$PALANG['confirm_delete_domain'] = 'Êtes-vous sûr de vouloir effacer tous les enregistrements du domaine %s ? Cette opération ne pourra pas être annulée.\n';
$PALANG['confirm_delete_fetchmail'] = 'Êtes-vous sûr de vouloir supprimer la tâche de récupération de courrier %s?';
$PALANG['confirm_delete_mailbox'] = 'Êtes-vous sûr de vouloir supprimer la boîte %s?';
$PALANG['confirm_delete_vacation'] = 'Êtes-vous sûr de vouloir supprimer le message d\'absence pour %s?';
$PALANG['no_delete_permissions'] = 'Vous n\'êtes pas autorisé à supprimer %s !';
$PALANG['confirm'] = 'Etes vous sur de vouloir supprimer cet enregistrement\n';
$PALANG['confirm_delete_admin'] = 'Do you really want to delete the admin %s?'; # XXX
$PALANG['confirm_delete_alias'] = 'Do you really want to delete the alias %s?'; # XXX
$PALANG['confirm_delete_aliasdomain'] = 'Do you really want to delete the alias domain %s?'; # XXX
$PALANG['confirm_delete_domain'] = 'Etes-vous sur de vouloir effacer tous les enregistrements dans ce domaine ? Cette opération ne pourra pas être annulée.\n (%s)'; # XXX text changed to: 'Do you really want to delete all records for the domain %s? This can not be undone'
$PALANG['confirm_delete_fetchmail'] = 'Do you really want to delete the fetchmail job %s?'; # XXX
$PALANG['confirm_delete_mailbox'] = 'Do you really want to delete the mailbox %s?'; # XXX
$PALANG['confirm_delete_vacation'] = 'Do you really want to delete the vacation message for %s?'; # XXX
$PALANG['no_delete_permissions'] = 'You are not allowed to delete %s!'; # XXX
$PALANG['check_update'] = 'Vérifier les mises à jour';
$PALANG['pCreate_alias_domain_error1'] = 'Vous n\'etes pas autorisé a créer la configuration choisie.';
$PALANG['pCreate_alias_domain_error2'] = 'La configuration choisie est invalide, merci d\'en choisir une autre!';
$PALANG['alias_domain_already_exists'] = 'Ce domaine est déjà un alias de domaine!';
$PALANG['alias_domain_does_not_exist'] = 'Ce domaine n\'est pas un alias de domaine!';
$PALANG['alias_domain_create_failed'] = 'Echec de la création de l\'alias de domaine!';
$PALANG['alias_domain_change_failed'] = 'Echec de la modification de l\'alias de domaine!';
$PALANG['pCreate_alias_domain_error4'] = 'Tous les domaines sont déjà un alias.';
$PALANG['pCreate_alias_domain_success'] = 'L\'alias de domaine %s a été créé.';
$PALANG['alias_domain_changed'] = 'L\'alias de domaine %s a été modifié.';
$PALANG['alias_domain_to_itsself'] = 'Un domaine ne peut pas être son propre alias!';
$PALANG['delete_domain_aliasdomain_target'] = 'Le domaine est la cible d\'un ou plusieurs alias de domaine et ne peut-être supprimé ! (Supprimez les alias de domaine d\'abord.)';
$PALANG['pCreate_alias_address_text_error1'] = 'Cet alias n\'est pas valide!';
$PALANG['alias_does_not_exist'] = 'Cet alias n\'existe pas!';
$PALANG['email_address_already_exists'] = 'Ce compte courriel existe déjà, choisissez-en un autre!';
$PALANG['alias_domain_to_itsself'] = 'Un domaine ne peut pas être son propre alias!';
$PALANG['delete_domain_aliasdomain_target'] = 'Le domaine est la cible d\un ou plusieurs alias de domains et ne peut-être supprimé! (Supprimez les alias de domaine d\'abord.)';
$PALANG['pCreate_alias_address_text_error1'] = 'Cet alias n\'est pas valide!';
$PALANG['alias_does_not_exist'] = 'Cet alias n\'existe pas!';
$PALANG['email_address_already_exists'] = 'Ce compte courriel existe déjà, choisissez-en un autre!';
$PALANG['pCreate_alias_goto_text'] = 'Destinataires des courriels.';
$PALANG['pCreate_alias_goto_text_error'] = 'le champ À contient des erreurs!';
$PALANG['pCreate_alias_result_error'] = 'Échec de la création de l\'alias %s !';
$PALANG['pCreate_alias_goto_text_error'] = 'le champ À contient des erreurs!';
$PALANG['pCreate_alias_result_error'] = 'Echec de la création de l\'alias %s!';
$PALANG['pCreate_alias_result_success'] = 'L\'alias %s a été ajouté !';
$PALANG['alias_updated'] = 'L\'alias %s a été mis à jour!';
$PALANG['pCreate_alias_catchall_text'] = 'Pour ajouter un alias global, utilisez "*". Pour un transfert de domaine à domaine, utilisez "*@domain.tld" dans le champ À.';
$PALANG['mailbox_alias_cant_be_deleted'] = 'Cet alias appartient à un compte courriel et ne peut donc pas être supprimé!';
$PALANG['protected_alias_cant_be_deleted'] = 'L\'alias %s est protégé et ne peut être supprimé que par un Super Administrateur.';
$PALANG['alias_updated'] = 'L\'alias %s a été mis à jour!'; # XXX
$PALANG['pCreate_alias_catchall_text'] = 'Pour ajouter un alias global, utilisez "*". Pour un transfert de domaine à domaine, utilisez "*@domain.tld" dans le champs A.'; # XXX check/beautify - was split in two lines before
$PALANG['mailbox_alias_cant_be_deleted'] = 'Cet alias appartient à un compte courriel et ne peut être supprimé!';
$PALANG['protected_alias_cant_be_deleted'] = 'The alias %s is protected and can only be deleted by a superadmin'; # XXX
$PALANG['pEdit_alias_welcome'] = 'Modifier les paramètres de transfert.';
$PALANG['pEdit_alias_help'] = 'Cibles multiples acceptées, une entrée par ligne.';
$PALANG['alias'] = 'Alias';
$PALANG['to'] = 'À';
$PALANG['pEdit_alias_goto_text_error1'] = 'Vous devez renseigner quelque chose dans le champ À';
$PALANG['pEdit_alias_goto_text_error2'] = 'L\'adresse email que vous avez indiqué est invalide: ';
$PALANG['pEdit_alias_domain_result_error'] = 'Impossible de modifier cet alias de domaine!';
$PALANG['pEdit_alias_forward_and_store'] = 'Conserver une copie des messages dans la boite aux lettres.';
$PALANG['pEdit_alias_forward_only'] = 'Transférer les messages sans conserver de copie.';
$PALANG['pEdit_alias_result_error'] = 'Échec de la modification de l\'alias %s !';
$PALANG['pEdit_alias_goto_text_error1'] = 'Vous devez entrer quelques choses dans le champ À';
$PALANG['pEdit_alias_goto_text_error2'] = 'L\'adresse courriel que vous avez entré est invalide: ';
$PALANG['pEdit_alias_domain_result_error'] = 'Impossible de modifier cet alias de domaine!';
$PALANG['pEdit_alias_forward_and_store'] = 'Transferer une copie.';
$PALANG['pEdit_alias_forward_only'] = 'Transferer les messages sans conserver de copie.';
$PALANG['pEdit_alias_result_error'] = 'Echec de la modification de l\'alias %s!';
$PALANG['pCreate_mailbox_welcome'] = 'Ajouter un nouveau compte courriel à votre domaine.';
$PALANG['pCreate_mailbox_username_text_error1'] = 'L\'adresse email est invalide !';
$PALANG['pCreate_mailbox_username_text_error3'] = 'Vous avez atteint le nombre maximum de comptes courriel !';
$PALANG['pCreate_mailbox_password_text'] = 'Mot de passe pour le compte POP3/IMAP';
$PALANG['pCreate_mailbox_username_text_error1'] = 'L\'adresse courriel est invalide!';
$PALANG['pCreate_mailbox_username_text_error3'] = 'Vous avez atteint le nombre maximum de compte courriel !';
$PALANG['pCreate_mailbox_password_text'] = 'Mot de passe pour compte POP3/IMAP';
$PALANG['pCreate_mailbox_email_desc'] = "Utilisé en cas d'oubli du mot de passe";
$PALANG['pCreate_mailbox_mail'] = 'Envoyer le message de bienvenue';
$PALANG['pCreate_mailbox_result_error'] = 'Échec de la création du compte courriel %s !';
$PALANG['pCreate_mailbox_result_success'] = 'Le compte courriel %s a été ajouté à la table des comptes!';
$PALANG['pCreate_mailbox_result_succes_nosubfolders'] = 'Le compte courriel %s a été ajouté à la table, mais un ou plusieurs dossiers prédéfinis n\'ont pu être créés!';
$PALANG['pCreate_mailbox_result_error'] = 'Echec de la création du compte courriel %s!';
$PALANG['pCreate_mailbox_result_success'] = 'Le compte courriel %s a été ajouté à la table des comptes!';
$PALANG['pCreate_mailbox_result_succes_nosubfolders'] = 'Le compte courriel %s a été ajouté à la table, mais un ou plusieurs dossiers prédéfinis n\'ont pu être créés!';
$PALANG['mailbox_updated'] = "Le compte courriel %s a été mis à jour.";
$PALANG['mailbox_update_failed'] = "Échec de la mise à jour du compte courriel %s !";
$PALANG['mailbox_update_failed'] = "Echec de la mise à jour du compte courriel %s!";
$PALANG['pEdit_mailbox_welcome'] = 'Modifier un compte courriel.';
$PALANG['pEdit_mailbox_password_text_error'] = 'Le mot de passe indiqué ne correspond pas !';
$PALANG['pEdit_mailbox_password_text_error'] = 'Le mot de passe entré ne correspond pas!';
$PALANG['pEdit_mailbox_quota'] = 'Limite';
$PALANG['pEdit_mailbox_quota_text'] = 'Mo';
$PALANG['pEdit_mailbox_quota_text'] = 'MB';
$PALANG['mb_max'] = 'Mo (max: %s)';
$PALANG['pEdit_mailbox_quota_text_error'] = 'La limite fournie est trop élevée !';
$PALANG['pEdit_mailbox_quota_text_error'] = 'La limite fournie est trop haute!';
$PALANG['pEdit_mailbox_domain_error'] = 'Ce domaine n\'est pas le votre: ';
$PALANG['pEdit_mailbox_result_error'] = 'Impossible de modifier le compte courriel !';
$PALANG['pPassword_welcome'] = 'Modifier votre mot de passe.';
$PALANG['pPassword_welcome'] = 'Changer votre mot de passe.';
$PALANG['pPassword_admin'] = 'Entrer';
$PALANG['pPassword_password_current'] = 'Mot de passe actuel';
$PALANG['pPassword_password_current_text_error'] = 'Vous n\'avez pas fourni le mot de passe actuel !';
$PALANG['pPassword_password_current_text_error'] = 'Vous n\'avez pas fournit le mot de passe actuel !';
$PALANG['pPassword_password'] = 'Nouveau mot de passe';
$PALANG['pPassword_password2'] = 'Nouveau mot de passe (confirmation)';
$PALANG['pPassword_password_text_error'] = 'Le mot de passe fourni ne correspond pas ou est vide!';
$PALANG['pPassword_password_text_error'] = 'Le mot de passe fourni ne correspond pas ou est vide!';
$PALANG['change_password'] = 'Changer le mot de passe';
$PALANG['pPassword_result_error'] = 'Impossible de changer le mot de passe de %s !';
$PALANG['pPassword_result_success'] = 'Le mot de passe de %s a été changé !';
$PALANG['pPassword_recovery_title'] = 'Suivez les instructions pour réinitialiser votre mot de passe.';
$PALANG['pPassword_recovery_button'] = 'Envoyez-moi le code';
$PALANG['pPassword_recovery_email_body'] = "Bonjour,\n\nUtilisez le lien suivant pour modifier votre mot de passe :\n%s\n\nSalutations,\n\n" . $CONF['admin_name'];
$PALANG['pPassword_recovery_sms_body'] = "Bonjour,\nLe code pour modifier votre mot de passe: %s\n" . $CONF['admin_name'];
$PALANG['pPassword_recovery_processed'] = "Nous avons traité votre demande. Si le nom d'utilisateur que vous avez saisi est valide, vous recevrez par e-mail/SMS un code de réinitialisation du mot de passe.";
$PALANG['pPassword_password_code'] = 'Code reçu par email/SMS';
$PALANG['pAdminCreate_admin_button'] = 'Ajouter un administrateur';
$PALANG['pAdminCreate_admin_result_error'] = 'L\'ajout de l\administrateur %s a échoué';
$PALANG['pAdminCreate_admin_result_success'] = 'L\'administrateur %s a été ajouté!';
$PALANG['pAdminCreate_admin_result_success'] = 'L\'administrateur %s a été ajouté!';
$PALANG['pAdminEdit_admin_welcome'] = 'Modifier un domaine';
$PALANG['admin'] = 'Administrateur';
$PALANG['password_again'] = 'Mot de passe (confirmation)';
$PALANG['super_admin'] = 'Super administrateur';
$PALANG['super_admin_desc'] = 'Les Super administrateurs ont accès à tous les domaines, ils peuvent gérer les domaines et les comptes d\'administrateur.';
$PALANG['pAdminEdit_admin_result_error'] = 'Impossible de modifier l\'administrateur %s!';
$PALANG['pAdminEdit_admin_result_success'] = 'L\'administrateur %s a été ajouté!';
$PALANG['super_admin_desc'] = 'Les Super administrateurs ont accès à tous les domaines, ils peuvent gérer les domaines et les comptes d\administrateur.';
$PALANG['pAdminEdit_admin_result_error'] = 'Impossible de modifier l\'administrateur %s!';
$PALANG['pAdminEdit_admin_result_success'] = 'L\'administrateur %s a été ajouté!';
$PALANG['pUsersLogin_welcome'] = 'Entrer votre adresse email pour modifier votre mot de passe et vos transferts.';
$PALANG['pUsersLogin_username_incorrect'] = 'L\'adresse email est invalide. Assurez-vous d\'avoir correctement saisi votre adresse email !';
$PALANG['pUsersLogin_password_incorrect'] = 'Votre mot de passe est invalide !';
$PALANG['pUsersLogin_password_recover'] = 'Mot de passe oublié';
$PALANG['pUsersLogin_welcome'] = 'Entrer votre adresse courriel pour modifier votre mot de passe et vos transferts.';
$PALANG['pUsersVacation_welcome_text'] = 'Le repondeur automatique pour l\'adresse %s est déjà configuré !';
$PALANG['pUsersVacation_welcome_text'] = 'Votre repondeur automatique est déjà configuré! (%s)'; # XXX Text changed to: 'Auto response for %s is active!'