# HG changeset patch # User Pascal Volk <user@localhost.localdomain.org> # Date 1637530533 0 # Node ID b678a1c430278b90cb4c1ca3f4ad791aa16354fc # Parent 659c4476c57ce41a673c9a7a98a5d33db5b345f0 Removed files -> Git: `git clone https://bitbucket.org/pvo/vmm.git` diff -r 659c4476c57c -r b678a1c43027 COPYING --- a/COPYING Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -Copyright (c) 2007 - 2014, Pascal Volk -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - 3. Neither the names of the authors nor the names of its contributors may be - used to endorse or promote products derived from this software without - specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff -r 659c4476c57c -r b678a1c43027 ChangeLog --- a/ChangeLog Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4168 +0,0 @@ -=== 0.6.2 === -2014-02-01 Pascal Volk <user@localhost.localdomain.org> - - * UPGRADE: - UPGRADE: Added a note about upgrading from 0.6.1. - [19184d1265e5] [tip] - - * doc/web/source/conf.py, doc/web/source/download.rst, - doc/web/source/features.rst, - doc/web/source/installation/install_vmm.rst, - doc/web/source/installation/postgresql_configuration.rst, - doc/web/source/pgsql_set_permissionspermissions.rst, - doc/web/source/release_history.rst, - doc/web/source/substitutions.rst, - doc/web/source/upgrade/0.5-0.6.rst: - doc/web: Updated documentation for vmm-0.6.2. - [6c369b680ab0] - - * update_config.py: - update_config: Updated to work with version 0.6.1. - [9149e0249c25] - -2014-01-29 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/domain.py: - VMM/domain: RE_DOMAIN: Check Punycode TLDs more precise. - [ad15e89a93ec] - -2014-01-27 Pascal Volk <user@localhost.localdomain.org> - - * COPYING, VirtualMailManager/__init__.py, - VirtualMailManager/account.py, VirtualMailManager/alias.py, - VirtualMailManager/aliasdomain.py, VirtualMailManager/catchall.py, - VirtualMailManager/cli/__init__.py, - VirtualMailManager/cli/clihelp.py, VirtualMailManager/cli/config.py, - VirtualMailManager/cli/handler.py, VirtualMailManager/cli/main.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py, - VirtualMailManager/config.py, VirtualMailManager/constants.py, - VirtualMailManager/domain.py, VirtualMailManager/emailaddress.py, - VirtualMailManager/errors.py, VirtualMailManager/ext/__init__.py, - VirtualMailManager/ext/postconf.py, VirtualMailManager/handler.py, - VirtualMailManager/mailbox.py, VirtualMailManager/maillocation.py, - VirtualMailManager/network.py, VirtualMailManager/password.py, - VirtualMailManager/pycompat/__init__.py, - VirtualMailManager/pycompat/hashlib.py, - VirtualMailManager/quotalimit.py, VirtualMailManager/relocated.py, - VirtualMailManager/serviceset.py, VirtualMailManager/transport.py, - pgsql/set-permissions.py, setup.py, update_config.py, vmm: - Updated copyright notices to include the year 2014. - [58815c004a61] - - * VirtualMailManager/handler.py: - VMM/handler: Improved domaininfo subcommand. - - Check all labels for ASCII-compatible encoding, not only the first - one. If something is in ACE format, convert it to IDNA. - [01db2457bbed] - -2014-01-26 Pascal Volk <user@localhost.localdomain.org> - - * README, VirtualMailManager/domain.py: - VMM/domain: Accept also ccTLDs and 'new' gTLDs. - [110491a871a7] - -2013-08-27 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/_templates/layout.html: - doc/web: Removed layout.html template. - [4c8e15c2f01b] - -2013-06-08 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/ext_references.rst, - doc/web/source/howto/manage_domains.rst, - doc/web/source/installation/dovecot_configuration.rst, - doc/web/source/installation/postfix_configuration.rst: - doc/web: Added a note about using Dovecot's LMTP with Postfix. This - solves issue #1. - [61aaa7a98ec0] - -2013-01-05 Pascal Volk <user@localhost.localdomain.org> - - * COPYING, VirtualMailManager/__init__.py, - VirtualMailManager/account.py, VirtualMailManager/alias.py, - VirtualMailManager/aliasdomain.py, - VirtualMailManager/cli/__init__.py, - VirtualMailManager/cli/clihelp.py, VirtualMailManager/cli/config.py, - VirtualMailManager/cli/handler.py, VirtualMailManager/cli/main.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py, - VirtualMailManager/config.py, VirtualMailManager/constants.py, - VirtualMailManager/domain.py, VirtualMailManager/emailaddress.py, - VirtualMailManager/errors.py, VirtualMailManager/ext/__init__.py, - VirtualMailManager/ext/postconf.py, VirtualMailManager/handler.py, - VirtualMailManager/mailbox.py, VirtualMailManager/maillocation.py, - VirtualMailManager/network.py, VirtualMailManager/password.py, - VirtualMailManager/pycompat/__init__.py, - VirtualMailManager/pycompat/hashlib.py, - VirtualMailManager/quotalimit.py, VirtualMailManager/relocated.py, - VirtualMailManager/serviceset.py, VirtualMailManager/transport.py, - setup.py, update_config.py, vmm: - Updated copyright notices to include the year 2013. - [d24f094d1cb5] - -2012-12-09 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/account.py: - VMM/account: Fixed a typo in Account.delete(). - - Due to a wrong placed comma `userdelete … force' ended in a - TypeError. - [29295afafa91] - -2012-11-21 Pascal Volk <user@localhost.localdomain.org> - - * po/fi.po: - po: Updated Finnish translation (translated by Jorma Karvonen). - [86c2ed36aba8] - -2012-11-03 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/installation/prerequisites.rst: - doc/web: Updated OpenBSD's package names. - [54172669bbae] - -2012-10-31 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/installation/postfix_configuration.rst: - doc/web: Fixed a typo. - [6f1aba75b693] - -2012-10-30 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/password.py: - VMM/password: Added scheme SCRAM-SHA-1. - [8ea32fbfc9df] - -2012-10-28 Pascal Volk <user@localhost.localdomain.org> - - * Configure.Dovecot_2, doc/web/source/_static/local.conf, - doc/web/source/installation/dovecot_configuration.rst: - Documentation: Fixed dictionary quota URI. - [152ea3e3e955] - - * install.sh: - install.sh: Don't fail if $SYSCONFDIR doesn't exist. - [9b4d0e2c97d5] - -2012-10-24 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/ext_references.rst: - doc/web/ext_references: Fixed URL of pg_hba.conf. - [c4c687668b6d] - -2012-10-19 Pascal Volk <user@localhost.localdomain.org> - - * README, doc/web/source/download.rst: - doc/web: Added links to the Debian package and the git repos. - - README: Added git-URL. - [8009e87c7a20] - -2012-10-03 Pascal Volk <user@localhost.localdomain.org> - - * .hgtags: - Added tag vmm-0.6.1 for changeset 682431c45b24 - [6463832d690e] - - * ChangeLog, NEWS, VirtualMailManager/constants.py, setup.py: - Released vmm-0.6.1 - [682431c45b24] [vmm-0.6.1] - -=== 0.6.1 === -2012-10-03 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/conf.py, doc/web/source/download.rst, - doc/web/source/howto/manage_accounts.rst, - doc/web/source/installation/install_vmm.rst, - doc/web/source/installation/postgresql_configuration.rst, - doc/web/source/pgsql_set_permissionspermissions.rst, - doc/web/source/release_history.rst, - doc/web/source/substitutions.rst, - doc/web/source/upgrade/0.5-0.6.rst: - doc/web: Updated documentation for vmm-0.6.1. - [f151defe7078] [tip] - -2012-10-02 martin f. krafft <madduck@madduck.net> - - * man/de/man1/vmm.1, man/man1/vmm.1: - Add list* commands to manpages - [ac27f89fad86] - -2012-10-01 Pascal Volk <user@localhost.localdomain.org> - - * UPGRADE: - UPGRADE: Added procedure for updating from v0.6.0. - [e1fc4a3075de] - -2012-09-30 Pascal Volk <user@localhost.localdomain.org> - - * update_config.py: - update_config: Updated to work with version 0.6.0. - - Fixed some PEP8 related issues. - [d7101e496795] - -2012-09-29 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/howto/general_subcommands.rst, - doc/web/source/howto/manage_alias_addresses.rst, - doc/web/source/howto/manage_catch-all_addresses.rst: - doc/web: Updated and extended documentation. - - Updated description of subcommands aliasdelete and catchalldelete. - Added description of subcommands listaddresses, listaliases, - listrelocated and listusers. - [e60b8ed5fd35] - - * VirtualMailManager/cli/clihelp.py: - VMM/cli/clihelp: Added missing help messages. - - Added descriptions of subcommands listaddresses, listaliases, - listrelocated and listusers. - [d8b60e53334f] - -2012-09-27 Pascal Volk <user@localhost.localdomain.org> - - * po/nl.po: - po: Updated Dutch translation (translated by Erwin Poeze). - [ca882a1ff90b] - - * VirtualMailManager/alias.py: - VMM/alias: Load destination addresses sorted. - - This produces sorted output for the aliasinfo subcommand. - [4ec5c015b7aa] - - * VirtualMailManager/alias.py, VirtualMailManager/catchall.py, - VirtualMailManager/cli/clihelp.py, - VirtualMailManager/cli/subcommands.py, - VirtualMailManager/handler.py, man/de/man1/vmm.1, man/man1/vmm.1: - VMM: {alias,catchall}delete: Accept multiple destinations. - [d8736bb80bdc] - -2012-09-24 Pascal Volk <user@localhost.localdomain.org> - - * po/nl.po: - po: Updated Dutch translation (translated by Erwin Poeze). - [9eecf0160c39] - -2012-09-23 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/cli/main.py: - VMM/cli/main: Check if we have warnings before exiting. - - If so, print them and exit afterwards. - [996bfcae49b0] - -2012-09-16 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/domain.py: - VMM/domain: Enabled transport-validation. - - Validate the transport also in Domain.set_transport() and - Domain.update_transport(). - [5882bfdf83e8] - - * VirtualMailManager/account.py, VirtualMailManager/common.py: - VMM: Moved transport-validation to common. - [1ec3497a6733] - -2012-09-15 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/account.py: - VMM/account: Fixed account's transport check. - - Make sure that 'virtual:' isn't used as transport when the mailbox- - format is set to mdbox or sdbox. - [7b3494f1a2ef] - -2012-09-12 Pascal Volk <user@localhost.localdomain.org> - - * po/nl.po: - po: Updated Dutch translation (translated by Erwin Poeze). - [924535664ecc] - -2012-09-05 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/account.py, VirtualMailManager/catchall.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py, - VirtualMailManager/config.py, VirtualMailManager/domain.py, - VirtualMailManager/handler.py: - PEP8: Fixed all PEP8 related issues. - [8e9b0046bc8f] - -2012-09-03 Pascal Volk <user@localhost.localdomain.org> - - * po/vmm.pot: - po: Regenerated vmm.pot - [b6c4e77046b9] - - * VirtualMailManager/cli/clihelp.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py: - Added a few comments for the Translation Project. - [56ec275911f2] - - * VirtualMailManager/catchall.py, VirtualMailManager/cli/clihelp.py, - VirtualMailManager/cli/subcommands.py, - VirtualMailManager/ext/postconf.py: - VMM: Corrected/updated some msgids. - - Unified some messages and corrected a few typos. - [0ed93eb8b364] - -2012-09-02 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Corrected username's usage string. - - username's name argument is optional. - [46454ff9d441] - - * VirtualMailManager/cli/clihelp.py, - VirtualMailManager/cli/subcommands.py: - VMM/cli: Activated help subcommand. - - Implemented Command.help_(), which reads the command's help message - from cli.clihelp. - [ab97727357a4] - - * VirtualMailManager/handler.py: - VMM/handler: Fixed user{quota,services,transport} subcommands. The - subcommands user{quota,services,transport} actually failed with the - arguments '<address> domain'. This is part II of changeset - a75923ce2842 - [b994444f7dee] - - * doc/web/source/howto/manage_accounts.rst: - doc/web: Added missing userservices description. Fixed order of - subcommand listing. - [7fdc4b2d4640] - - * man/man1/vmm.1: - man: Typo-fix. - [981f02b2d4c5] - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Corrected two usage strings. domainnote's and - usernote's note argument is optional. - [af88f01e5bfa] - -2012-09-01 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py: - VMM: Decode localized numbers to the current encoding. That avoids - UnicodeDecodeErrors since locale.format(%d) may return localized - numbers, which contain NO-BREAK SPACE as the thousands separator. - [463b10c258d9] - -2012-08-28 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Don't mark empty strings as translatable. - gettext('') returns the header entry with meta information, not the - empty string. - [0571f45501da] - - * doc/web/source/upgrade/0.5-0.6.rst: - doc/web: Added description 'Upgrade to Dovecot ≧ v1.2.beta2'. - [82e722f35aab] - -2012-08-27 Pascal Volk <user@localhost.localdomain.org> - - * pgsql/dovecot_update_v1.2+.pgsql: - pgsql: Added dovecot_update_v1.2+.pgsql. Use this file when you are - upgrading your Dovecot installation to a version >= 1.2.beta2. - [bb23693e5fc9] - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Reverted accidentally committed help() code. - [c79fdce49908] - - * VirtualMailManager/cli/subcommands.py, pgsql/create_tables.pgsql: - pgsql/create_tables.pgsql: Eliminated two unnecessary differences. - Yeah, cosmetic only. - [607aa5c2acc4] - - * pgsql/create_tables.pgsql, pgsql/update_tables_0.5.x-0.6.pgsql: - pgsql: Don't select service_set.ssid in dovecotpassword() - unconditional. This may cause an empty result, which will make - logins impossible. - [86b967c0f1a1] - - * VirtualMailManager/serviceset.py: - VMM/serviceset: Fixed a conditional ProgrammingError. Affects only - setups with Dovecot < v1.2.beta2. Actually the SQL query in method - ServiceSet._load_by_services wasn't updated. - - Removed unnecessary code, which would have also produced a - ProgrammingError, if it would have been correct. - [cdbe200c0ecc] - -2012-08-23 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Added 'missing' newline below domain notes. - This patch contains also a small code cleanup and PEP8-fix. - [3dc1764c23d2] - -2012-08-19 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/howto/manage_accounts.rst: - doc/web: Added the transport filed to the usertransport example. - [ef384bc8fde6] - -2012-08-12 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/howto.rst, - doc/web/source/howto/general_subcommands.rst, - doc/web/source/howto/manage_accounts.rst, - doc/web/source/howto/manage_alias_addresses.rst, - doc/web/source/howto/manage_alias_domains.rst, doc/web/source/howto - /manage_catch-all_addresses.rst, - doc/web/source/howto/manage_domains.rst, - doc/web/source/howto/manage_relocated_users.rst, - doc/web/source/index.rst, - doc/web/source/installation/install_vmm.rst: - doc/web: Added the 'Howto'. The reStructuredText version of vmm.1, - in multiple parts. - [2b165e90e225] - - * man/de/man1/vmm.1, man/man1/vmm.1: - man/{de/}man1: A few more corrections. - [9d343514b832] - - * man/de/man1/vmm.1, man/man1/vmm.1: - man/{de/}man1: Small corrections for domaininfo's description. - [60907fc875f7] - - * man/de/man5/vmm.cfg.5, man/man5/vmm.cfg.5: - man/{de/}man5: s/Wiki/Homepage/g - [dcde0010cdf8] - -2012-08-11 Pascal Volk <user@localhost.localdomain.org> - - * man/de/man1/vmm.1, man/man1/vmm.1: - man/{de/}man1: s/Wiki/Homepage/g - [8767ec854084] - -2012-08-08 martin f. krafft <madduck@debian.org> - - * VirtualMailManager/common.py: - VMM/common: Improve search_address complexity Checking the - dictionary (a hash) for existence of a key is likely to be - O(log(n)), while checking a list is O(n). Therefore, to increase - performance, this patch changes the check accordingly. - [cd1200d06700] - -2012-08-07 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/_static/vmm.cfg: - doc/web: Refreshed vmm.cfg - [ffd24974ed68] - - * vmm.cfg: - vmm.cfg: Updated/improved comments. - [f9a2327f57a6] - -2012-08-07 martin f. krafft <madduck@debian.org> - - * VirtualMailManager/common.py: - If an alias has multiple destinations, multiple records exist, due - to the nature of the database. address_list would then return the - same alias multiple times, which does not add any information, eats - screen space and is potentially confusing. - - Therefore, we SELECT DISTINCTly from the alias table. - - Signed-off-by: martin f. krafft <madduck@debian.org> - --- VirtualMailManager/common.py | 2 +- 1 file changed, 1 - insertion(+), 1 deletion(-) - [a479c38931c4] - - * VirtualMailManager/common.py: - Due to the UNION query in address_list, the assumption that the list - of gids received from the database would be continuous does not - hold. - - To prevent addresses for domains with multiple entry types from - being listed, it is necessary to check the list of domain gids for - every entry. - - Signed-off-by: martin f. krafft <madduck@debian.org> - --- VirtualMailManager/common.py | 4 +--- 1 file changed, 1 - insertion(+), 3 deletions(-) - [605f8c115711] - -2012-07-29 Pascal Volk <user@localhost.localdomain.org> - - * doc/web/source/installation/dovecot_configuration.rst, - doc/web/source/installation/postgresql_configuration.rst: - doc/web: Emphasized a few lines of Dovecot/PostgreSQL configuration - file excerpts. - [9c138471d569] - - * .hgignore: - .hgignore: "doc/build" is no longer required. - [b62210b96ea7] - - * doc/web/Makefile, doc/web/source/_static/local.conf, - doc/web/source/_static/vmm.cfg, doc/web/source/_static/vmm_logo.png, - doc/web/source/_templates/layout.html, doc/web/source/conf.py, - doc/web/source/download.rst, doc/web/source/ext_references.rst, - doc/web/source/features.rst, doc/web/source/index.rst, - doc/web/source/install.rst, - doc/web/source/installation/dovecot_configuration.rst, - doc/web/source/installation/install_vmm.rst, - doc/web/source/installation/postfix_configuration.rst, - doc/web/source/installation/postgresql_configuration.rst, - doc/web/source/installation/prerequisites.rst, - doc/web/source/installation/system_preparation.rst, - doc/web/source/pgsql_set_permissionspermissions.rst, - doc/web/source/release_history.rst, - doc/web/source/substitutions.rst, doc/web/source/upgrade.rst, - doc/web/source/upgrade/0.4.x-0.5.rst, - doc/web/source/upgrade/0.5-0.6.rst, doc/web/source/vmm.cfg.rst: - doc: Added source of http://vmm.localdomain.org/. - [be0906181a10] - - * doc/Makefile, doc/api/Makefile, doc/api/source/conf.py, - doc/api/source/index.rst, doc/api/source/vmm.rst, - doc/api/source/vmm_alias.rst, doc/api/source/vmm_config.rst, - doc/api/source/vmm_constants_error.rst, - doc/api/source/vmm_emailaddress.rst, doc/api/source/vmm_errors.rst, - doc/api/source/vmm_relocated.rst, doc/source/conf.py, - doc/source/index.rst, doc/source/vmm.rst, doc/source/vmm_alias.rst, - doc/source/vmm_config.rst, doc/source/vmm_constants_error.rst, - doc/source/vmm_emailaddress.rst, doc/source/vmm_errors.rst, - doc/source/vmm_relocated.rst: - doc: Moved API documentation to doc/api. - [20141b967c0b] - -2012-07-22 Pascal Volk <user@localhost.localdomain.org> - - * INSTALL: - INSTALL: Updated PostgreSQL configuration URL. Use ${sql} and - ${proxysql} expressions in the main.cf description. - [4f9079dd4b65] - -2012-07-01 Pascal Volk <user@localhost.localdomain.org> - - * README: - README: Substituted a few words. - [0be27a75776a] - -2012-06-30 Pascal Volk <user@localhost.localdomain.org> - - * README: - README: Updated URL of the hg repository@sf.net. - [f9e6e0a237f0] - - * man/man1/vmm.1: - man: Deleted erroneous placed backslash. - [9acf628bf0be] - -2012-06-28 Pascal Volk <user@localhost.localdomain.org> - - * .hgtags: - Added tag vmm-0.6.0 for changeset 3238c58d01ae - [0643c25121b5] - - * ChangeLog, NEWS, VirtualMailManager/constants.py, setup.py: - Released vmm-0.6.0 - [3238c58d01ae] [vmm-0.6.0] - -=== 0.6.0 === -2012-06-28 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/Exceptions.py, - VirtualMailManager/MailLocation.py, VirtualMailManager/Relocated.py, - VirtualMailManager/Transport.py, - VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/constants/ERROR.py, - VirtualMailManager/constants/EXIT.py, - VirtualMailManager/constants/VERSION.py, - VirtualMailManager/constants/__init__.py, - VirtualMailManager/ext/Postconf.py, pgsql - /create_optional_types_and_functions-dovecot-1.2.x.pgsql, - pgsql/create_optional_types_and_functions.pgsql, - pgsql/update_tables_0.4.x-0.5.pgsql, - pgsql/update_tables_0.5.x_for_dovecot-1.2.x.pgsql, - pgsql/update_types_and_functions_0.5.x_for_dovecot-1.2.x.pgsql, - postfix/pgsql-transport.cf, update_config_0.4.x-0.5.py: - Merged changes from v0.6.x(28230a8230bf). - [a4aead244f75] [tip] - - * Close v0.6.x branch. - [28230a8230bf] <v0.6.x> - - * vmm: - vmm: Don't insert the module directory into sys.path by default. - Doesn't make much sense, if the code is installed inside sys.path. - [54a84a311654] <v0.6.x> - - * COPYING, VirtualMailManager/__init__.py, - VirtualMailManager/account.py, VirtualMailManager/alias.py, - VirtualMailManager/aliasdomain.py, - VirtualMailManager/cli/__init__.py, - VirtualMailManager/cli/config.py, VirtualMailManager/cli/handler.py, - VirtualMailManager/cli/main.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py, - VirtualMailManager/config.py, VirtualMailManager/constants.py, - VirtualMailManager/domain.py, VirtualMailManager/emailaddress.py, - VirtualMailManager/errors.py, VirtualMailManager/ext/__init__.py, - VirtualMailManager/ext/postconf.py, VirtualMailManager/handler.py, - VirtualMailManager/mailbox.py, VirtualMailManager/maillocation.py, - VirtualMailManager/network.py, VirtualMailManager/password.py, - VirtualMailManager/pycompat/__init__.py, - VirtualMailManager/pycompat/hashlib.py, - VirtualMailManager/quotalimit.py, VirtualMailManager/relocated.py, - VirtualMailManager/serviceset.py, VirtualMailManager/transport.py, - setup.py, update_config.py, vmm: - Updated copyright notices to include the year 2012. - [14abdd04ddf5] <v0.6.x> - - * TODO: - TODO: Removed "listpwschemes" entry. Was done with changeset - a64c1b5e08b4 - [11ed67ee7ebb] <v0.6.x> - - * UPGRADE: - UPGRADE: Updated documentation. - [007786e58fb7] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, man/de/man1/vmm.1, - man/man1/vmm.1: - VMM/cli/subcommands: Replaced the keyword `default' by `domain'. - Patch by Martin F. Krafft - [a75923ce2842] <v0.6.x> - -2012-06-27 Pascal Volk <user@localhost.localdomain.org> - - * Configure.Dovecot_2, INSTALL: - INSTALL: Added description how to create additional dove* - user/group. `doveauth' user and group for the authentication process - and the group `dovemail' for mail related Dovecot processes. - [55148bc6348e] <v0.6.x> - - * INSTALL: - INSTALL: Updated documentation. - [b17a9d7a59ae] <v0.6.x> - - * Configure.Dovecot_2, install.sh, upgrade.sh: - Configure.Dovecot_2: Added configuration documentation for Dovecot_2 - >= 2.0. - [b5bb7b34e831] <v0.6.x> - - * VirtualMailManager/account.py, - VirtualMailManager/cli/subcommands.py: - VMM: The Python 2.4.x compatibility commit - part III. - [b0165b7af7a3] <v0.6.x> - - * VirtualMailManager/account.py: - VMM/account: Check the account's transport only when we have a - transport. - [2662f4e17eb4] <v0.6.x> - - * VirtualMailManager/account.py, - VirtualMailManager/cli/subcommands.py, - VirtualMailManager/handler.py: - VMM: The Python 2.4.x compatibility commit. - [cc0f67f99780] <v0.6.x> - -2012-06-14 Pascal Volk <user@localhost.localdomain.org> - - * pgsql/set-permissions.py: - pgsql/set-permissions.py: Extended permissions. Postfix needs read - access on the postfix_gid view. Dovecot needs read permissions on - both mailboxformat columns. - [2fcf12fdecc2] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Restored method Handler.domain_transport(). It went - somehow lost with changeset 5806fb74130b. - [1498abbb6c91] <v0.6.x> - -2012-05-31 Pascal Volk <user@localhost.localdomain.org> - - * pgsql/set-permissions.py: - pgsql: Added helper script: set-permissions.py. - [fbbb16476c5b] <v0.6.x> - -2012-04-15 martin f. krafft <madduck@madduck.net> - - * TODO, VirtualMailManager/cli/handler.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py, - VirtualMailManager/constants.py, VirtualMailManager/handler.py: - Provide list{addresses,aliases,users,relocated} subcommands - - The patch provides the list{addresses,aliases,users,relocated} - subcommands to the UI. All commands actually take the same path in - the code and only one query is run with different parameters for - each case. - - There are still two shortcomings: - - 1. With alias domains, the output order is not as one might want - it, e.g. - - foo@example.org bar@example.org - foo@example.com bar@example.com - - when it should really be foo@ twice and then bar@ twice. I have - not found a way to modify the SQL accordingly. - - 2. The SELECT queries for Accounts, Alias and Relocated are hard- - coded in common.py. - [499c63f52462] <v0.6.x> - - * man/de/man1/vmm.1, man/de/man5/vmm.cfg.5, man/man1/vmm.1, - man/man5/vmm.cfg.5: - man: escape hyphens - - Hyphens inside words must be spelt \- instead of just -. This patch - fixes up the manpages. - * * * . - [a93671970617] <v0.6.x> - - * man/de/man1/vmm.1, man/man1/vmm.1: - man: add 'catchall' to domaininfo - - Since the addition of catchall, the domaininfo subcommand can also - take 'catchall' as a [detail] to limit the output of details to the - catch-all aliases. - - Also, the number of catch-all destinations is now included in the - simple domaininfo output. - [6f2c41c3c7d6] <v0.6.x> - -2012-04-15 Pascal Volk <user@localhost.localdomain.org> - - * man/de/man1/vmm.1, man/man1/vmm.1: - man: vmm1: Use `fqdn' instead of `domain' in catchall* descriptions. - Fixed a typo s/cadd/cad/. Replaced double quotes by \(dq. - [107f7a3be9f5] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Use the `fqdn' argument placeholder also for - catch-all subcommands. - [62f2daff853e] <v0.6.x> - -2012-04-15 martin f. krafft <madduck@madduck.net> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Fix transport_maps function for non-existent domains - - The postfix_transport_maps function had a bug causing - - 2012-04-15 17:40:22 CEST LOG: statement: SELECT transport FROM - postfix_transport_map('logcheck', 'domine.madduck.net'); - 2012-04-15 17:40:22 CEST ERROR: query returned no rows - - when the domain was not in the database. This would make did be NULL - and make the query fail. - - This patch moves the tid query until after a check for did. If the - latter is NULL, the function RETURNs (rather than fails). - [867d950ce7b7] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Revert caching of destination interpolation - - Since 'destination' comes from the table in the query, it cannot be - cached across queries! Doh! - [44a808af6cf4] <v0.6.x> - -2012-04-15 Pascal Volk <user@localhost.localdomain.org> - - * pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - pgsql: update_tables_*: Added missing `NOT' to `… tid DROP NOT - NULL;'. - [92ef34f07da3] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql: - pgsql: Create column `note' as text. - [5020c56f9388] <v0.6.x> - -2012-04-15 martin f. krafft <madduck@madduck.net> - - * VirtualMailManager/common.py: - Add docstring for common.format_domain_default - [79f09cdd1a21] <v0.6.x> - -2012-04-14 martin f. krafft <madduck@madduck.net> - - * man/de/man1/vmm.1, man/man1/vmm.1: - Document domainnote in manpages - - 5806fb74130b did not contain this, so I must have forgotten it. - Oops. - [47254b46c361] <v0.6.x> - - * TODO: - Remove domain/account notes from TODO - [ff805bd17817] <v0.6.x> - - * VirtualMailManager/account.py: - Include account note in getuser output - - Modify the getuser output to include an account note, if one is - present - [1b3bdce0bf87] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - Display formatted notes in info output - - If the user/domain object has an attached note, this patch makes the - userinfo/domaininfo output print the note, wrapped to the terminal - size. - [c3b98364f03d] <v0.6.x> - - * .hgignore: - Ignore *.egg-status build directory created by setuptools - [a582f1452bc0] <v0.6.x> - - * man/de/man1/vmm.1, man/man1/vmm.1: - Add user/domainnote commands to manpages - [a8ee0328f908] <v0.6.x> - - * VirtualMailManager/account.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/domain.py, - VirtualMailManager/handler.py: - Add note field to Account/Domain and CLI - [5806fb74130b] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Modify SQL to add note field to domain_data and users - [1f9ea5658627] <v0.6.x> - -2012-04-14 Pascal Volk <user@localhost.localdomain.org> - - * man/de/man1/vmm.1, man/man1/vmm.1: - man: vmm.1: subcommand's name argument is optional now. Based on - martin f. krafft's v2 of changeset c340ba4bd544. - [9a23043b0530] <v0.6.x> - -2012-04-14 martin f. krafft <madduck@madduck.net> - - * VirtualMailManager/cli/subcommands.py, - VirtualMailManager/handler.py, man/de/man1/vmm.1, man/man1/vmm.1: - Allow username to take no argument to erase value - - Once a username has been set, it could not be removed via the UI. - Now, if no argument is passed to username, the value stored is - replaced with NULL. - [c340ba4bd544] <v0.6.x> - - * README: - Add inheritance as a feature to README - [e956ddc868c0] <v0.6.x> - - * VirtualMailManager/domain.py, man/de/man1/vmm.1, man/man1/vmm.1: - Change 'force' argument to reset user records for tid/ssid/qid - - If domain{quotalimit,transport,serviceset} are run with 'force' and - settings are inheritable from the domain, then rather than to copy - the ID to the user table, the affected field in the user records - should be set to NULL so that the domain default is used. - [6a27c7529cd7] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, - VirtualMailManager/handler.py, man/de/man1/vmm.1, man/man1/vmm.1: - Change UI to accept 'default' to restore inherited values - - Instead of explicit values for tid/ssid/qid, the UI now accepts - 'default', which removed user-pecific settings and hence causes - domain defaults to be used. - [2676dbf43e1c] <v0.6.x> - -2012-04-13 martin f. krafft <madduck@madduck.net> - - * VirtualMailManager/account.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py: - Modify userinfo output to indicate when domain defaults are - displayed - - When Account instances reference NULL tid/qid/ssid, the data must - come from the associated domain, and this should be indicated. For - transport and services, this is easy to do as the string passed in - the info dict can simply be modified. For quotalimit, however, - another method must be used due to the CLI-side formatting. - - All approaches use a common formatter outsourced to the common.py - file. - [2bb40aaef94e] <v0.6.x> - - * VirtualMailManager/account.py: - Modify Account class to handle NULL references - - This patch modifies the Account class to defer to using the - associated domain's tid/ssid/qid fields if the per-instance fields - are None/NULL. - [cf3eb03c1c4f] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Modify SQL update script to accept NULL fields for users - - The value NULL in the qid/ssid/tid fields of the user table means - that the value from the associated domain record should be used - instead. - - This patch modifies the PL/pgSQL functions used by Dovecot and - Postfix accordingly. - [95dd123b552e] <v0.6.x> - - * man/de/man1/vmm.1, man/man1/vmm.1: - man: Add examples for userservices - [916b468cf994] <v0.6.x> - -2012-04-14 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/account.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py, - pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Reverted previous three changesets (e09139525580, 85517c8fde36, - 3acbff727626) - [4b8c3f51d7da] <v0.6.x> - -2012-04-13 martin f. krafft <madduck@madduck.net> - - * VirtualMailManager/account.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py: - Modify userinfo output to indicate when domain defaults are - displayed - - When Account instances reference NULL tid/qid/ssid, the data must - come from the associated domain, and this should be indicated. For - transport and services, this is easy to do as the string passed in - the info dict can simply be modified. For quotalimit, however, - another method must be used due to the CLI-side formatting. - - All approaches use a common formatter outsourced to the common.py - file. - [e09139525580] <v0.6.x> - - * VirtualMailManager/account.py: - Modify Account class to handle NULL references - - This patch modifies the Account class to defer to using the - associated domain's tid/ssid/qid fields if the per-instance fields - are None/NULL. - [85517c8fde36] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Modify SQL update script to accept NULL fields for users - - The value NULL in the qid/ssid/tid fields of the user table means - that the value from the associated domain record should be used - instead. - - This patch modifies the PL/pgSQL functions used by Dovecot and - Postfix accordingly. - [3acbff727626] <v0.6.x> - -2012-04-14 martin f. krafft <madduck@madduck.net> - - * TODO: - Add list* subcommands to TODO - [3ffe4ee3740f] <v0.6.x> - - * TODO: - add domain/account notes to TODO - [f494a593c674] <v0.6.x> - -2012-04-13 martin f. krafft <madduck@madduck.net> - - * TODO: - Add my WIP items to the TODO list - [dc66f66c51cf] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Cache interpolated destination - - Instead of running the string modification function for destination - interpolation twice, store the result once and use the stored result - subsequently. - [75d1c0d6bb8f] <v0.6.x> - -2012-04-12 Pascal Volk <user@localhost.localdomain.org> - - * man/man1/vmm.1: - man: Use example.com in catchallinfo example output. - [a0a27688e616] <v0.6.x> - - * README: - README: reStructuredText fix: ERROR/3 and WARNING/2. - [b1fd6f08f369] <v0.6.x> - -2012-04-11 martin f. krafft <madduck@madduck.net> - - * README, man/de/man1/vmm.1, man/man1/vmm.1, pgsql/create_tables- - dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Enable interpolation of alias destinations - - This patch modifies the virtual_alias_maps function so that the - destination address is parsed for the place holders %n, %d and %=, - which are replaced with the localpart, the domain or the full - address with '@' replaced by '=' of the queried key. - - In combination with alias domains, this allows for domain-specific - recipients. - - E.g. given example.org and its alias domain example.com, defining an - alias - - postmaster@example.org → postmaster+%d@example.org - - will cause mail to postmaster@example.*com* to go to - postmaster+example.*com*@example.org. - [5ec2068d02af] <v0.6.x> - - * README: - Add catch-all aliases to README/features - [88466a6ba3ae] <v0.6.x> - -2012-04-10 martin f. krafft <madduck@madduck.net> - - * man/de/man1/vmm.1, man/man1/vmm.1: - Add catchall subcommands to manpages - [b2084e7f6854] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, VirtualMailManager/domain.py, - pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Include catch-all count in domaininfo output - [09fa019bb330] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Make PL/pgSQL function feed back identity for mailboxes/relocated - when there are catchall destinations. - - Without catchall aliases, if no virtual_alias matches, the query can - just return NULL and Postfix will later check mailboxes/relocated - for the address to rewrite. - - However, since virtual aliases are handled long before - mailboxes/relocated, a catchall alias would also catch mail to - mailboxes and relocated addresses, which we do not want. - - The way to tell postfix to keep delivering is for the virtual alias - map to return the search key itself (identity function). - - This patch changes the postfix_virtual_alias_maps Pl/pgSQL function - to do exactly that, but only if there are catchall destinations - defined for the domain in question — otherwise it returns NULL when - no match is found. - [d863a44a6353] <v0.6.x> - - * VirtualMailManager/catchall.py: - Fix syntax errors - [557c4703986c] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Modify virtual_alias_maps function to check mailboxes/relocated - first - [821d3ffaaaca] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Make virtual_alias_maps function search catchall when no aliases are - found - [0244f1344b04] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, VirtualMailManager/domain.py, - VirtualMailManager/handler.py: - Add catchall info to domain_info output - [1fa354bbdb90] <v0.6.x> - - * VirtualMailManager/catchall.py: - Correct syntax errors - [1a9247e9763f] <v0.6.x> - -2012-04-09 martin f. krafft <madduck@madduck.net> - - * VirtualMailManager/handler.py: - Fixup catchall_info to return iterator, not self - [18870919ec48] <v0.6.x> - - * VirtualMailManager/catchall.py: - Correct syntax errors - [2aae58cddfa9] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - Teach CLI about catchall* commands - [fb0ffde628d6] <v0.6.x> - - * VirtualMailManager/handler.py: - Provide catchall_* methods to the Handler class - [3da8c919584f] <v0.6.x> - - * VirtualMailManager/catchall.py: - First version of a CatchallAlias class - - I based the CatchallAlias class in catchall.py heavily on the Alias - class, but by copy, not deriving. The two are functionally related, - but the implementations are too different because CatchallAliases - have no localpart. - [f180ead60568] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - Add database table for catchall destinations - - Catch-all aliases are stored for a domain. Since there can be - multiple destinations per domain, this is done using a 1:n relation - on the gid. - - This commit extends the SQL schema definition and also provides - appropriate upgrade DDL. - [492c179094c9] <v0.6.x> - -2012-04-08 Pascal Volk <user@localhost.localdomain.org> - - * pgsql/create_optional_types_and_functions-dovecot-1.2.x.pgsql, - pgsql/create_optional_types_and_functions.pgsql, pgsql - /create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql, - pgsql/update_types_and_functions_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_types_and_functions_0.5.x-0.6.pgsql: - pgsql: Merged types and functions into the create_tables… files. - [e1b32377032f] <v0.6.x> - - * postfix/pgsql-relocated_maps.cf, postfix/pgsql-transport_maps.cf, - postfix/pgsql-virtual_alias_maps.cf, postfix/pgsql- - virtual_mailbox_maps.cf, postfix/pgsql-virtual_uid_maps.cf: - postfix: Removed VIEW-based comments from configuration files. - [f2387d60624b] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - pgsql: Removed most of the VIEWs. - - There are only two views left for now: - - postfix_gid - - vmm_domain_info - - All other views have a faster replacement: plpgsql functions. - [5ccc9c6e5193] <v0.6.x> - -2012-04-08 martin f. krafft <madduck@madduck.net> - - * .hgignore: - Ignore even more Debian-build-related files - [23d04d1f29e8] <v0.6.x> - - * .hgignore: - Ignore more Debian-build-related files - - Debian produces log and debhelper files in debian/* that do not need - to be known to mercurial. Hence, this patch adds the globs to - .hgignore. - [419c929739fd] <v0.6.x> - - * TODO: - Add non-root TODO - [5b9a03762813] <v0.6.x> - -2012-04-07 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/config.py: - VMM/config: Fixed a typo: s/DB_MUDULES/DB_MODULES/g. - [17f2c5b5098e] <v0.6.x> - -2012-04-07 martin f. krafft <madduck@madduck.net> - - * .hgignore: - Ignore build files related to Debian packaging - - During Debian packaging, the package is built in ./debian/vmm/, and - quilt is used (./.pc/). Both directories contain only generated - files and should hence be ignored from the perspective of Mercurial. - [612a60e9d558] <v0.6.x> - - * .hgignore: - Instruct mercurial to ignore build directory - - Python's distutil builds the package into ./build/, which can and - should be ignored with respect to the repository. This patch simply - adds the appropriate line to .hgignore. - [2c5e2613eca8] <v0.6.x> - -2012-04-06 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/handler.py: - VMM/handler: Create domain directory with umask 0022. - [30365a87650d] <v0.6.x> - -2012-04-07 martin f. krafft <madduck@madduck.net> - - * VirtualMailManager/domain.py: - Modify address check query to obtain well-defined result - - The way in which UNION does not yield the desired result, because - (a) UNION merges results and (b) the result order is undefined. This - patch changes the query to select the counts as columns and hence - provides a well-defined order. - [e5c2b3647971] <v0.6.x> - -2012-04-06 Pascal Volk <user@localhost.localdomain.org> - - * postfix/pgsql-smtpd_sender_login_maps.cf: - postfix: Uncommented the query in pgsql-smtpd_sender_login_maps.cf. - [320531aa1280] <v0.6.x> - - * postfix/pgsql-transport.cf, postfix/pgsql-transport_maps.cf: - postfix: Renamed pgsql-transport.cf to pgsql-transport_maps.cf. Now - it matches pgsql-${postfix-parameter}.cf. - [9cdc6ef83265] <v0.6.x> - -2012-03-29 Pascal Volk <user@localhost.localdomain.org> - - * po/fr.po: - po: Updated French translation (translated by Dimitri Duc). - [e0441b07bccc] <v0.6.x> - -2012-03-13 Pascal Volk <user@localhost.localdomain.org> - - * po/fi.po: - po: Updated Finnish translation (translated by Jorma Karvonen). - [b8d5564b4e42] <v0.6.x> - -2011-12-13 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Fixed a TypeError in user_info(). - [fb0af82ab4af] <v0.6.x> - -2011-12-05 Pascal Volk <user@localhost.localdomain.org> - - * postfix/pgsql-relocated_maps.cf, postfix/pgsql-transport.cf, postfix - /pgsql-virtual_alias_maps.cf, postfix/pgsql-virtual_mailbox_maps.cf, - postfix/pgsql-virtual_uid_maps.cf: - postfix: Use pgsql functions in query templates where possible. - [ccdfbbb1bb01] <v0.6.x> - - * pgsql/create_optional_types_and_functions-dovecot-1.2.x.pgsql, - pgsql/create_optional_types_and_functions.pgsql: - pgsql: Updated required privileges for function dovecotpassword. - [10e9b4855173] <v0.6.x> - -2011-11-27 Pascal Volk <user@localhost.localdomain.org> - - * README: - README: Added section `Installation Prerequisites'. Reworked some - parts. - [35395b49bc44] <v0.6.x> - -2011-11-26 Pascal Volk <user@localhost.localdomain.org> - - * update_config.py, upgrade.sh: - update_config: Write the old package install dir to a tmp file. - - upgrade: Remove old CamelCase files. Removed some unused variables. - [fb210a116f18] <v0.6.x> - -2011-11-13 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/serviceset.py: - VMM: The pyPgSQL compatibility commit. - [428ee9cdf1b2] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, VirtualMailManager/config.py: - VMM: The Python 2.4.x compatibility commit. - [90d69ae4f40d] <v0.6.x> - - * VirtualMailManager/relocated.py: - VMM/relocated: Don't accept something@localhost as destination. - [099de308fd98] <v0.6.x> - - * man/de/man1/vmm.1, man/man1/vmm.1: - man1: Updated configuration related descriptions/examples, - accordingly to commit 4ff0fa3ba0fa. - [b33bdc0c3669] <v0.6.x> - -2011-11-12 Pascal Volk <user@localhost.localdomain.org> - - * VirtualMailManager/constants.py, man/de/man1/vmm.1, - man/de/man5/vmm.cfg.5, man/man1/vmm.1, man/man5/vmm.cfg.5, setup.py: - Updated the author's e-mail address. - [6278a7a2a476] <v0.6.x> - -2011-11-12 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man1/vmm.1, man/de/man5/vmm.cfg.5, man/man1/vmm.1, - man/man5/vmm.cfg.5: - man: Updated the URL of the bug tracker. - [86fa217cba11] <v0.6.x> - -2011-11-11 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man5/vmm.cfg.5, man/man5/vmm.cfg.5: - man5: Updated the `usable password schemes' part. - [c30ce0e079b6] <v0.6.x> - -2011-11-10 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man1/vmm.1, man/man1/vmm.1: - man1: Copied new formatted/translated command output into the - examples. - [e321b764268e] <v0.6.x> - -2011-11-09 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Small improvement of domaininfo's output. - Pointed out that the displayed quota limit is valid per user. - [4353981e3a7f] <v0.6.x> - - * man/de/man1/vmm.1, man/man1/vmm.1: - man1: Removed obsolete commands and added new commands. - [9b9cccebccf0] <v0.6.x> - - * man/de/man1/vmm.1: - man/de/man1: Removed translated argument names. - [8f59a2f539e7] <v0.6.x> - -2011-11-08 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Use the common output formatting in - list_pwschemes(). - [5d0114f7bb99] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Added a comment for the Translation Project. - [807ad4df0774] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Subcommand argument placeholders are no longer - translatable. - [1ebb6b88f589] <v0.6.x> - -2011-11-07 Pascal Volk <neverseen@users.sourceforge.net> - - * po/de.po: - po: Updated German translation (translated by Mario Blättermann). - [89bf9389d62f] <v0.6.x> - - * po/vmm.pot: - po: Updated address for message-id bug reports. Looks like as sf.net - would have horrible configured mail servers. :-/ - [b4d21e8bfa00] <v0.6.x> - - * merged changes from default(c0e1fb1b0145) - [863c691d7d14] <v0.6.x> - - * po/fi.po: - po: Added Finnish translation to the repository. Many thanks to - Jorma Karvonen from the Translation Project for the work. - [c0e1fb1b0145] - - * VirtualMailManager/password.py: - VMM/password: list_schemes(): report suffixes with a leading dot. - [7d4d79ff08d0] <v0.6.x> - - * po/de.po, po/vmm.pot: - po: Updated messages template and German translation. - [b175c9f62602] <v0.6.x> - -2011-11-06 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Added new subcommand `listpwschemes' (lp). - Marked version()'s ctx argument as unused. - [a64c1b5e08b4] <v0.6.x> - - * VirtualMailManager/password.py: - VMM/password: Added function list_schemes(). - [cabdf94ec580] <v0.6.x> - - * man/de/man5/vmm.cfg.5, man/man5/vmm.cfg.5: - man5: Moved some option descriptions to section doamin, accordingly - to commit 4ff0fa3ba0fa. Added a brief explanation of which settings - will be applied in which situations. - [e57dd007d69a] <v0.6.x> - -2011-11-05 Pascal Volk <neverseen@users.sourceforge.net> - - * update_config.py: - update_config: Updated, so that the previous config modifications - will be applied to 0.5.2 configurations files. - [033a0436894f] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, VirtualMailManager/config.py, - VirtualMailManager/handler.py, vmm.cfg: - VMM/config: Moved some options to section `domain': - - old new - ------------------------------------------------------------ - account.imap -> domain.imap account.pop3 - -> domain.pop3 account.sieve -> domain.sieve - account.smtp -> domain.account - - misc.quota_bytes -> domain.quota_bytes - misc.quota_messages -> domain.quota_messages misc.transport - -> domain.transport - [4ff0fa3ba0fa] <v0.6.x> - - * VirtualMailManager/__init__.py: - VMM: Show a warning when a unsupported locale setting was detected. - [2019aa415dcd] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Small improvement in domain_add(). Inform the - admin, when the postmaster account will be auto-created. - [7847f949d0a2] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Fixed a small failure in alias_info(). - [b15960e9c53c] <v0.6.x> - - * TODO: - TODO: updated … - [7d27627c7fb0] <v0.6.x> - - * VirtualMailManager/domain.py: - VMM/domain: Extended Domain._chk_state() to support both states. - [f2934105181b] <v0.6.x> - -2011-11-04 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/constants.py: - VMM/constants: Cleared out obsolete error codes. - [63ae77f05088] <v0.6.x> - - * VirtualMailManager/account.py: - VMM/account: Removed unused import. - [2408a3cd4bea] <v0.6.x> - - * VirtualMailManager/maillocation.py, - VirtualMailManager/quotalimit.py: - VMM/{maillocation,quotalimit}: Unified object initialization code. - Simply raise a ValueError for wrong values (unknown IDs). - [fd4aa073015f] <v0.6.x> - - * VirtualMailManager/errors.py, VirtualMailManager/transport.py: - VMM/transport: Reworked Transport initialization. Set the transport - id only if we could find a transport with that id. Raise a - ValueError instead of a translatable TransportError(VMMError). - VMM/errors: Deleted class TransportError, it is no longer needed. - [6826acb9b0a7] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: domainservices: Don't fail when neither a - service nor the keyword force was provided. - [45c917e6a386] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, VirtualMailManager/domain.py, - VirtualMailManager/handler.py: - VMM/domain: Extended/updated Domain.get_info() in order to: - - include active service(s) || None - - use more understandable English terms - - VMM/cli/subcommands: Updated (order of) keys of `domaininfo' output. - .`userinfo' will always show `sieve', no longer `managesieve'. - [c31d604e26d3] <v0.6.x> - -2011-11-03 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Small indent fix. - [18b75e6a39d5] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Added subcommand domainservices (ds). Replaced - subcommands userdisable and userenable by userservices (us). - [b8c94e06cd46] <v0.6.x> - -2011-11-02 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/account.py, VirtualMailManager/handler.py: - VMM/account: Integrated class ServiceSet in class Account. Replaced - methods Account.enable() and Account.disable() by - Account.update_serviceset(). VMM/handler: Replaced methods - Handler.user_disable() and Handler.user_enable() by - Handler.user_services() - [95275b61ff8a] <v0.6.x> - -2011-11-01 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/serviceset.py: - VMM/serviceset: Added @property ServiceSet.services -> dict. - [e2b9e3de2b51] <v0.6.x> - - * VirtualMailManager/account.py: - VMM/account: Sorted imports … - [abcd73f5e980] <v0.6.x> - - * VirtualMailManager/domain.py, VirtualMailManager/handler.py: - VMM/domain: Integrated class ServiceSet in class Domain. - VMM/handler: Extended Handler.domain_add() and added - Handler.domain_services(). Removed unused domain.get_gid import. - [1af5fe0683ce] <v0.6.x> - - * VirtualMailManager/serviceset.py: - VMM/serviceset: Use SERVICES inside of ServiceSet - avoid slicing. - [1a08fe35b496] <v0.6.x> - -2011-10-31 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/serviceset.py: - VMM/serviceset: Added module constant SERVICES. - [39036f5e6387] <v0.6.x> - -2011-10-30 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/serviceset.py: - VMM: Added new module serviceset - provides class ServiceSet. - [e35efe931af3] <v0.6.x> - -2011-10-28 Pascal Volk <neverseen@users.sourceforge.net> - - * pgsql/create_optional_types_and_functions-dovecot-1.2.x.pgsql, - pgsql/create_optional_types_and_functions.pgsql, pgsql - /create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql, - pgsql/update_types_and_functions_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_types_and_functions_0.5.x-0.6.pgsql: - pgsql: Added new table `service_set'. Moved columns `smtp', `pop3' - `imap' and `sieve' from the `users' table to the new `service_set' - table. - [9823548b2717] <v0.6.x> - -2011-10-26 Pascal Volk <neverseen@users.sourceforge.net> - - * update_config.py: - update_config: Set database.module to pyPgSQL only when psycopg2 is - unavailable. - [d296a020f440] <v0.6.x> - - * README: - README: Added contet. - [ee6f8ac06197] <v0.6.x> - - * man/de/man1/vmm.1.rst, man/de/man5/vmm.cfg.5.rst, - man/substitute_links.rst, man/substitute_links_1.rst, - man/substitute_links_5.rst: - man: Removed reStructuredText files. - [3ca31d080432] <v0.6.x> - - * man/de/man1/vmm.1, man/de/man5/vmm.cfg.5: - man: Reworked/updated German manual pages. - [c2543ddde9f5] <v0.6.x> - -2011-10-25 Pascal Volk <neverseen@users.sourceforge.net> - - * man/man1/vmm.1: - man: Added missing `.RE' macro to sub section userinfo (ui). - [ad7cfbfbc68d] <v0.6.x> - -2011-10-16 Pascal Volk <neverseen@users.sourceforge.net> - - * po/de.po: - po: Fixed 2 fatal msgfmt errors inde.po. - [fdd05a757f43] <v0.6.x> - - * po/de.po: - po: Updated German translation. - [c11edcfc6e5f] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, po/vmm.pot: - Messages: Replaced some 'Available' by 'Existing'. - [9842650569c2] <v0.6.x> - - * po/vmm.pot: - po: Regenerated vmm.pot - [0d8e7977ae63] <v0.6.x> - -2011-09-03 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/emailaddress.py: - VMM/emailaddress: Class DestinationEmailAddress accepts also - something@localhost addresses now. - [8e41e77b84e6] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Handler.alias_delete() also use class - DestinationEmailAddress for the destination address, instead of - class EmailAddress. - [933b9debbec1] <v0.6.x> - - * VirtualMailManager/alias.py: - VMM/alias: Alias.del_destination() corrected the value assignment in - the error message's dictionary. - [8394e222aba3] <v0.6.x> - - * VirtualMailManager/alias.py: - VMM/alias: Alias._load_dests() use class DestinationEmailAddress for - destination addresses, instead of class EmailAddress. - [46c296c6e231] <v0.6.x> - -2011-07-31 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: user_add() show only generated passwords - not - the given. - [a43a2e20de71] <v0.6.x> - -2011-03-10 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/handler.py, - VirtualMailManager/ext/postconf.py, VirtualMailManager/handler.py, - VirtualMailManager/mailbox.py: - VMM: Deleted a few unused variables. - [33a45e4c80c4] <v0.6.x> - -2011-03-05 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/network.py: - VMM/network: Added new module network. - [ff2a61e155db] <v0.6.x> - -2011-02-27 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/main.py, - VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Added function update_cmd_map(). So the items - will be added to the cmd_map when gettext's _() has been installed - -> translatable subcommand descriptions. - [d4a341248500] <v0.6.x> - -2011-02-24 Pascal Volk <neverseen@users.sourceforge.net> - - * po/vmm.pot: - po: Regenerated vmm.pot - [241b192bfcc8] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: The keyword 'force' is no longer translatable. - [542a4d23a9f0] <v0.6.x> - - * VirtualMailManager/account.py, VirtualMailManager/alias.py, - VirtualMailManager/aliasdomain.py, - VirtualMailManager/cli/__init__.py, - VirtualMailManager/cli/handler.py, VirtualMailManager/cli/main.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/domain.py, - VirtualMailManager/emailaddress.py, - VirtualMailManager/ext/postconf.py, VirtualMailManager/handler.py, - VirtualMailManager/password.py, VirtualMailManager/relocated.py: - VMM: Updated some messages. (doesn't, isn't) -> (does not, is not) - Added missing dots at the end of some sentences. - [8209da83e256] <v0.6.x> - - * man/man1/vmm.1, man/man5/vmm.cfg.5: - man: Replaced unnecessary \(aq glyphs in man1/vmm.1. Updated COPYING - section in man1/vmm.1 and man5/vmm.cfg.5. - [f32b323fd347] <v0.6.x> - -2011-02-22 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/mailbox.py: - VMM/mailbox: Use the correct mailbox hierarchy separator in - Mailbox.add_boxes() for mdbox and sdbox mailbox format. - [c7a963e6cf6e] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py: - VMM: Report quota usage/limit/percentage values formatted according - to the current LC_ALL setting. - [ae1a8428298c] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Improved legibility of domaininfo's "quota - limit" output a little bit. - [e5b3b225bd5b] <v0.6.x> - - * man/man5/vmm.cfg.5, man/man5/vmm.cfg.5.rst: - man/man5: Reworked/updated vmm.cfg.5. Removed vmm.cfg.5.rst. - [65687300ba19] <v0.6.x> - - * man/man1/vmm.1: - man/man1: Small syntax fixes in vmm.1. - [1ca025a5ce0c] <v0.6.x> - -2011-02-21 Pascal Volk <neverseen@users.sourceforge.net> - - * man/man1/vmm.1, man/man1/vmm.1.rst: - man/man1: Reworked/updated vmm.1. Removed vmm.1.rst. - reStructuredText was nice to edit but the generated output … - [2bc9c36c1387] <v0.6.x> - -2011-02-18 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Update also the RunContext's subcommand if - 'plan A' in {,alias}domain_info() fails. - [54a89c19e534] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Fixed a msgid issue (format string with unnamed - arguments). - [f6e55b27fe07] <v0.6.x> - - * VirtualMailManager/handler.py, VirtualMailManager/quotalimit.py: - VMM: Solve the default "misc.quota_bytes = '0'" problem where it may - occur. - [3162ff959375] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Made argument names translatable. - [58e23bd7c97f] <v0.6.x> - -2011-02-14 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man1/vmm.1.rst, man/man1/vmm.1.rst, - man/substitute_links_1.rst: - man1/vmm.1.rst: Added subcommands domainquota and userquota. Updated - description of subcommand aliasadd. - [da80de422b3c] <v0.6.x> - -2011-02-13 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/account.py, VirtualMailManager/domain.py: - VMM/{account,domain}: Added a versions check to the - update_quotalimit methods of classes Account and Domain. - [0c52094447b0] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Implemented subcommands domainquota and - userquota. - [a4f5d4cd886d] <v0.6.x> - - * VirtualMailManager/domain.py: - VMM/domain: Execute the database updates of - Domain.update_{quotalimit,transport}() when argument force is True, - even when the 'new' setting is the same as the current one. - [8984b1f4e6e3] <v0.6.x> - -2011-02-12 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Divided 'quota usage' from userinfo subcommand - into 'quota storage' and 'quota messages'. - [00a8c12a3da3] <v0.6.x> - - * VirtualMailManager/quotalimit.py: - VMM/quotalimit: Don't fail in QuotaLimit.__init__, if we get the - deafult misc.quota_bytes value: '0'. - [0512d940918f] <v0.6.x> - - * VirtualMailManager/common.py: - VMM/common: Reworked human_size() once more. Return bytes w/o - prefix. Use translatable $FOO_bibyte prefixes, e.g., MiB. - [fb22773f7a85] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Added quota limit/usage output to - {domain,user}info subcommands. - [3e5ed678d535] <v0.6.x> - -2011-02-11 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: config_get: Print configured misc.quota_bytes - in human readable format. - [cf661a40266d] <v0.6.x> - - * VirtualMailManager/common.py: - VMM/common: human_size() size argument can be also a string. Because - the default value of misc.quota_bytes is '0', a string in order to - accept also settings like '500M'. - [7f931c1ca059] <v0.6.x> - - * VirtualMailManager/common.py: - VMM/common: human_size accept also 0 as size. - [0a13849243f2] <v0.6.x> - - * VirtualMailManager/common.py: - VMM/common: Small code cleanup in human_size(). - [d3a3c6155879] <v0.6.x> - - * VirtualMailManager/common.py: - VMM/common: Added function human_size(). - [fb2ba1456bc5] <v0.6.x> - -2011-02-10 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/domain.py: - VMM/domain: Adjusted Domain.get_info() to the updated - vmm_domain_info view. - [ffce67e3c6eb] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - pgsql: Updated view vmm_domain_info. No longer select data we have - already. - [8217ddd5220d] <v0.6.x> - - * VirtualMailManager/account.py, VirtualMailManager/domain.py, - VirtualMailManager/handler.py: - VMM/{account,domain,handler}: Added quota limit support. A few small - modifications in class Account. - [660b42391c8e] <v0.6.x> - -2011-02-09 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/account.py: - VMM/account: Removed unused method Account.set_transport(). - [5f7e9f778b29] <v0.6.x> - -2011-02-08 Pascal Volk <neverseen@users.sourceforge.net> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - pgsql: Added quotalimit's bytes and messages to view - vmm_domain_info. - [dd95ed5bc9d2] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql: - pgsql/{create,update}_tables*: Added the ON DELETE CASCADE clause to - table userquota{,_11}'s foreign-key constraint - fkey_userquota_uid_users. - [05dc4e1f8dff] <v0.6.x> - -2011-02-07 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/mailbox.py: - VMM/mailbox: Added missing dummy translator (_) and comment for - method Mailbox._add_boxes. - [b7854259ad74] <v0.6.x> - - * VirtualMailManager/quotalimit.py: - VMM/quotalimit: Added new module quotalimit to the repository. - [0cae9989395b] <v0.6.x> - -2011-02-06 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/config.py, man/de/man5/vmm.cfg.5.rst, - man/man5/vmm.cfg.5.rst, vmm.cfg: - VMM/config: Added quota_bytes and quota_messages settings. Updated - …/man5/vmm.cfg.5 and vmm.cfg. - [d3a97f7fb98a] <v0.6.x> - -2011-02-04 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/common.py: - VMM/common: Added function size_in_bytes(). - [ac5ac03b58da] <v0.6.x> - - * pgsql/create_optional_types_and_functions-dovecot-1.2.x.pgsql, - pgsql/create_optional_types_and_functions.pgsql, pgsql - /create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql, - pgsql/update_types_and_functions_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_types_and_functions_0.5.x-0.6.pgsql: - pgsql/*: Added tables, triggers and functions for quota support. - [5e6bcb2e010e] <v0.6.x> - -2011-02-02 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/handler.py: - VMM:/handler: Fixed typo introduced with the previous commit. - [98223e5c95e0] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Handler._make_domain_dir(): Check if the domain - directory exists before calling os.mkdir(). - [5aaf2dd6b146] <v0.6.x> - - * VirtualMailManager/alias.py, VirtualMailManager/aliasdomain.py, - VirtualMailManager/domain.py, VirtualMailManager/relocated.py, - VirtualMailManager/transport.py: - VMM/*: Use target column names in all INSERT statements. In order to - avoid trouble after the definition of a table was changed. - [7518d927d443] <v0.6.x> - -2011-02-01 Pascal Volk <neverseen@users.sourceforge.net> - - * INSTALL: - INSTALL: Updated "user_query". - [af56cee51e67] <v0.6.x> - -2011-01-28 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/mailbox.py: - VMM/mailbox: Be more detailed if doveadm couldn't create mailboxes. - [920cb090eb09] <v0.6.x> - -2011-01-20 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/subcommands.py: - VMM/cli/subcommands: Update also the RunContext's subcommand if - 'plan A' in {alias,relocated,user}_info() fails. - [2af61bc06215] <v0.6.x> - - * VirtualMailManager/cli/handler.py, VirtualMailManager/handler.py: - VMM/{,cli/}handler: Moved the 'address-in-use check' (introduced - with changeset ef99be5b7ec0) to {alias,relocated,user}_add(). - [4cbaf8d229f9] <v0.6.x> - -2011-01-19 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/account.py: - VMM/account: Account._count_aliases() cast the EmailAddress to str, - in order to avoid errors from the database. - [ecdba68c7a2c] <v0.6.x> - -2011-01-17 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/handler.py: - VMM/handler: Handler.relocated_add() check if the target address' - domain is known, if so add a warning when the account/alias doesn't - exist. - [1016a17684c1] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Handler._get_{account,alias,relocated}() check if the - address is already in use. - [ef99be5b7ec0] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Handler.alias_add() and Handler.relocated_add() use - DestinationEmailAddress instances for target addresses. - [3b2fd0b4e51b] <v0.6.x> - -2011-01-17 Tobias Berling <t-obi@users.sourceforge.net> - - * VirtualMailManager/alias.py: - VMM/alias.py: Fixed TypeError when calling dbc.executemany() - [1b1f8f0cc687] <v0.6.x> - - * setup.py: - setup.py: Fixed syntax error - [4dfc5f3c1f2c] <v0.6.x> - - * pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql: - pgsql/create_tables{,-dovecot-1.2.x}.pgsql: Fixed syntax errors - [be4bd77dbe57] <v0.6.x> - -2011-01-17 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/emailaddress.py: - VMM/emailaddress: Added class DestinationEmailAddress. - [a6ad9895989d] <v0.6.x> - -2011-01-14 Pascal Volk <neverseen@users.sourceforge.net> - - * COPYING, VirtualMailManager/__init__.py, - VirtualMailManager/account.py, VirtualMailManager/alias.py, - VirtualMailManager/aliasdomain.py, - VirtualMailManager/cli/__init__.py, - VirtualMailManager/cli/config.py, VirtualMailManager/cli/handler.py, - VirtualMailManager/cli/main.py, - VirtualMailManager/cli/subcommands.py, VirtualMailManager/common.py, - VirtualMailManager/config.py, VirtualMailManager/constants.py, - VirtualMailManager/domain.py, VirtualMailManager/emailaddress.py, - VirtualMailManager/errors.py, VirtualMailManager/ext/__init__.py, - VirtualMailManager/ext/postconf.py, VirtualMailManager/handler.py, - VirtualMailManager/mailbox.py, VirtualMailManager/maillocation.py, - VirtualMailManager/password.py, - VirtualMailManager/pycompat/__init__.py, - VirtualMailManager/pycompat/hashlib.py, - VirtualMailManager/relocated.py, VirtualMailManager/transport.py, - setup.py, update_config.py, vmm: - Updated copyright notices to include the year 2011. - [d6573da35b5f] <v0.6.x> - -2011-01-13 Pascal Volk <neverseen@users.sourceforge.net> - - * INSTALL: - merged changes from default(cfd29e65e4f2) - [61fdd77d2e65] <v0.6.x> - - * INSTALL: - INSTALL: Use the %L modifier for %u variable in password_query and - user_query. - [cfd29e65e4f2] - -2010-08-10 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/domain.py: - VMM/domain: set_{directory,transport} make sure the domain is new. - Assertions could be optimized away. - [502d59f4bb34] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, man/de/man1/vmm.1.rst, - man/man1/vmm.1.rst, man/substitute_links_1.rst: - VMM/cli/subcommands: Added 'auto postmaster' to domain_add(). - [c2e8eab2616d] <v0.6.x> - - * VirtualMailManager/cli/handler.py, - VirtualMailManager/cli/subcommands.py, man/de/man1/vmm.1.rst, - man/man1/vmm.1.rst, man/substitute_links_1.rst: - VMM/cli/handler: Added support for random passwords in user_add(). - [971577b89d26] <v0.6.x> - -2010-08-09 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/transport.py: - VMM/transport: Small error message 'improvement'. - [44283818f8db] <v0.6.x> - - * VirtualMailManager/config.py: - VMM/config: Added option mailbox.format to the configuration check. - [7fa919dab42c] <v0.6.x> - - * update_config.py: - update_config: Set pyPgSQL, maybe there is no psycopg2 installed. - [6fabb9cd212d] <v0.6.x> - - * man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst: - man5/vmm.cfg: Added description for new settings in section - database. - [095b43faaba5] <v0.6.x> - - * INSTALL, setup.py: - Updated INSTALL and setup.py. - [61e732e4cb3e] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Added support for psycopg2. - [48bf20b43f2e] <v0.6.x> - - * VirtualMailManager/cli/main.py: - VMM/cli/main: Adjusted _get_handler() to changes in config module. - [a653c43048b1] <v0.6.x> - - * VirtualMailManager/config.py: - VMM/config: Extended configuration check and raise only a - ConfigError. Added new settings 'module', 'port', and 'sslmode' to - the database section. - [2ae40cd0d213] <v0.6.x> - -2010-08-07 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/account.py, VirtualMailManager/alias.py, - VirtualMailManager/aliasdomain.py, VirtualMailManager/domain.py, - VirtualMailManager/maillocation.py, VirtualMailManager/relocated.py, - VirtualMailManager/transport.py: - VMM/…: Provide parameters as tuple to cursor.execute(). - [22d115376e4d] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Small code cleanups. - [4bba5fb90b78] <v0.6.x> - - * VirtualMailManager/common.py: - VMM/common: Reformulated error message in exec_ok. - [b7a4d7828608] <v0.6.x> - - * VirtualMailManager/cli/config.py: - VMM/cli/config: Except the VMMError from exec_ok in configure(). - [d60ffbc0124b] <v0.6.x> - - * VirtualMailManager/config.py: - VMM/config: Use common.VERSION_RE, instead of defining the regexp - two times. - [ca7575401549] <v0.6.x> - - * VirtualMailManager/common.py: - VMM/common: Made the version re pattern object accessible as - VERSION_RE. Small 'global …' cleanups. - [586367ee042b] <v0.6.x> - -2010-08-06 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/handler.py: - VMM/cli/handler: Don't perform config and environment checks twice. - [95d45e4ec1a6] <v0.6.x> - - * VirtualMailManager/cli/subcommands.py, man/de/man1/vmm.1.rst, - man/man1/vmm.1.rst: - VMM/cli/subcommands: Added subcommands configget and configset. - [f8d5c8bb8bce] <v0.6.x> - - * VirtualMailManager/cli/config.py: - VMM/cli/config: CliConfig.set raise a ConfigError, if the new value - could not be set. - [0d2430dc6ef8] <v0.6.x> - - * VirtualMailManager/cli/main.py: - VMM/cli/main: Except more errors and handle them correct. - [9232ed7e4d85] <v0.6.x> - - * VirtualMailManager/config.py: - VMM/config: LazyConfig._get_section_option check for empty - section/option names. - [b0c971f943dc] <v0.6.x> - -2010-08-05 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/account.py, VirtualMailManager/cli/config.py, - VirtualMailManager/cli/handler.py, - VirtualMailManager/cli/subcommands.py, - VirtualMailManager/emailaddress.py, VirtualMailManager/handler.py, - VirtualMailManager/relocated.py, po/vmm.pot: - VMM/…: Unified messages and removed non-ASCII quotes. VMM/account: - Added TP-comment back. Was accidentally removed in changeset - f9a6b6701cf9. Refreshed po/vmm.pot. - [6709d0faf2f5] <v0.6.x> - - * VirtualMailManager/cli/__init__.py, VirtualMailManager/cli/main.py, - VirtualMailManager/cli/subcommands.py, vmm: - vmm: Renamed to VirtualMailManager/cli/main.py. Splitted subcommands - out to VirtualMailManager/cli/subcommands.py. vmm: New created with - minimal code. - [4515afec62e5] <v0.6.x> - - * VirtualMailManager/cli/handler.py: - VMM/cli/handler: CliHandler.user_password: Only prompt for the - password if the Account exists. - [abff2de9eed0] <v0.6.x> - - * VirtualMailManager/account.py: - VMM/account: Made Account._services available as account.SERVICES. - [45834dcc280e] <v0.6.x> - -2010-08-04 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/handler.py, VirtualMailManager/handler.py: - VMM/{,cli/}handler: user_add: Check earlier if the account exists. - [150ddcc8b315] <v0.6.x> - -2010-08-03 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/domain.py: - VMM/domain: Added missing comma in Domain.get_info's SELECT list. - [d24c2ea39710] <v0.6.x> - -2010-08-01 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/handler.py, man/de/man1/vmm.1.rst, - man/man1/vmm.1.rst: - VMM/handler: Updated Handler.user_{disable,enable} methods to accept - a list of services. man/{,de/}man1/vmm.1.rst: Updated - userenable/userdisable part. - [7a471cace3ba] <v0.6.x> - - * VirtualMailManager/account.py: - VMM/account: Reworked methods enable/disable in order to accept - multiple services. - [3f550826b1cc] <v0.6.x> - -2010-07-30 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/account.py, VirtualMailManager/handler.py, - man/de/man1/vmm.1.rst, man/man1/vmm.1.rst: - VMM/{account,handler}: Account delete, use the boolean keyword force - too. - [1ed85e696748] <v0.6.x> - - * man/de/man1/vmm.1.rst, man/man1/vmm.1.rst: - man/{,de/}man1/vmm.1.rst: Updated domaindelete part. - [352ca7f1b332] <v0.6.x> - - * VirtualMailManager/domain.py, VirtualMailManager/handler.py: - VMM/domain: Simplified Domain.delete() related methods and their - arguments, VMM/handler: Adjusted to the changes in the domain - module. - [270b57af85de] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: _make_home() Create the domain directory if it doesn't - exist for some reason. - [3fe8d6cdbe3a] <v0.6.x> - - * VirtualMailManager/account.py, VirtualMailManager/handler.py: - VMM/account: Replaced property domain_directory by domain. - [41789df75339] <v0.6.x> - -2010-07-29 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/common.py: - VMM/common: Removed unused import. - [85972d3ba936] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Use more common.lisdir() in Handler's methods _chkenv, - _delete_domain_dir, _delete_home, _get_disk_usage, _make_domain_dir, - and _make_home. Handler._make_home(): Also check if the domain - directory exists. - [bb9ff81928f1] <v0.6.x> - - * VirtualMailManager/common.py, VirtualMailManager/config.py, - VirtualMailManager/mailbox.py: - VMM/common: Replaced function is_dir() by lisdir(). - VMM/{config,mailbox}: Adjusted to the above change. - [8f8d9c4c8332] <v0.6.x> - - * VirtualMailManager/handler.py: - VMM/handler: Reworked methods _get_disk_usage, _delete_home and - _delete_domain_dir. Deleted method _isdir. - [06c0457036a0] <v0.6.x> - - * VirtualMailManager/constants.py: - VMM/constants: Added MIN_GID and MIN_UID. - [38e344ba3d0f] <v0.6.x> - -2010-07-28 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/mailbox.py: - VMM/mailbox: Removed accidentally committed debug print statement. - [d58cc465dc61] <v0.6.x> - - * VirtualMailManager/alias.py, VirtualMailManager/cli/config.py, - VirtualMailManager/config.py, VirtualMailManager/emailaddress.py, - VirtualMailManager/mailbox.py, VirtualMailManager/relocated.py: - VMM/…: More PEP-8 fixes; eliminated __names. VMM/emailaddress: - Fixed™ methods __eq__ and __ne__. (I'm not pylint's nanny.) - [94bd10e237e5] <v0.6.x> - - * VirtualMailManager/transport.py: - VMM/transport: Converted _mixedCase method names to - _lower_case_with_underscores. Added missing docstrings. Fixed™ - methods __eq__ and __ne__. (I'm not pylint's nanny.) - [883d5cd66498] <v0.6.x> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/Handler.py, VirtualMailManager/Relocated.py, - VirtualMailManager/Transport.py, VirtualMailManager/__init__.py, - VirtualMailManager/account.py, VirtualMailManager/alias.py, - VirtualMailManager/aliasdomain.py, VirtualMailManager/cli/Config.py, - VirtualMailManager/cli/Handler.py, - VirtualMailManager/cli/__init__.py, - VirtualMailManager/cli/config.py, VirtualMailManager/cli/handler.py, - VirtualMailManager/common.py, VirtualMailManager/config.py, - VirtualMailManager/domain.py, VirtualMailManager/emailaddress.py, - VirtualMailManager/errors.py, VirtualMailManager/ext/Postconf.py, - VirtualMailManager/ext/postconf.py, VirtualMailManager/handler.py, - VirtualMailManager/mailbox.py, VirtualMailManager/maillocation.py, - VirtualMailManager/password.py, VirtualMailManager/relocated.py, - VirtualMailManager/transport.py: - VMM/*: Made all modules names lowercase, adjusted imports. - [011066435e6f] <v0.6.x> - - * VirtualMailManager/Handler.py, VirtualMailManager/cli/Handler.py: - VMM//{,cli/}Handler: PEP-8-ified the Handler classes: - * converted CamelCase method names to lower_case_with_underscores - * eliminated __names - * added missing docstrings - [f4956b4ceba1] <v0.6.x> - -2010-07-27 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Handler.py, VirtualMailManager/cli/Handler.py: - VMM//{,cli/}Handler: Reworked configuration related parts. Renamed - attributes _Cfg -> _cfg; _cfgFileName -> _cfg_fname. Renamed methods - __chkCfgFile -> __check_cfg_file; __findCfgFile -> __find_cfg_file. - Added missing docstrings. - [4dc2edf02d11] <v0.6.x> - - * VirtualMailManager/constants.py: - VMM/constants: Added __copyright__. - [d619e97a8f18] <v0.6.x> - -2010-07-26 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/Handler.py, VirtualMailManager/Relocated.py, - VirtualMailManager/Transport.py, VirtualMailManager/__init__.py, - VirtualMailManager/cli/Config.py, VirtualMailManager/cli/Handler.py, - VirtualMailManager/cli/__init__.py, VirtualMailManager/common.py, - VirtualMailManager/constants.py, - VirtualMailManager/constants/ERROR.py, - VirtualMailManager/constants/EXIT.py, - VirtualMailManager/constants/__init__.py, - VirtualMailManager/constants/version.py, - VirtualMailManager/ext/Postconf.py, VirtualMailManager/mailbox.py, - VirtualMailManager/maillocation.py, VirtualMailManager/password.py: - VMM/constants: Replaced the constants subpackage by a module. - [31d8931dc535] <v0.6.x> - - * VirtualMailManager/cli/__init__.py: - VMM/cli: Forgot to remove string_io from __all__. - [81bccfd14355] <v0.6.x> - - * VirtualMailManager/cli/__init__.py: - VMM/cli: Removed misplaced function string_io. - [0b4a6e9d9f27] <v0.6.x> - - * VirtualMailManager/cli/Config.py: - VMM/cli/Config: Write warnings to stderr. Renamed method - __saveChanges to __save_changes. - [c17c46d9e440] <v0.6.x> - - * VirtualMailManager/cli/__init__.py: - VMM/cli: w_err() call os.sys.exit only if code != 0. read_pass() - write errors to stderr. And a few other small fixes. - [6f39a1e56f4a] <v0.6.x> - -2010-07-25 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/ext/Postconf.py: - VMM/ext/Postconf: Reworked class Postconf. Added method edit(). - [a0a10100aee5] <v0.6.x> - -2010-07-23 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Handler.py: - VMM/Handler: Reworked __domDirMake and reamed to __make_domain_dir. - Removed the (now) unused method __makedir. - [644e2cc4a441] <v0.6.x> - - * VirtualMailManager/Handler.py, VirtualMailManager/mailbox.py: - VMM/mailbox: Added to the repository. VMM/Handler: Integrated - mailbox module. Code cleanups. - [d21423478803] <v0.6.x> - - * VirtualMailManager/Transport.py: - VMM/Transport: Small cosmetics. - [aa4a9fc31e1b] <v0.6.x> - - * VirtualMailManager/maillocation.py, man/de/man5/vmm.cfg.5.rst, - man/man5/vmm.cfg.5.rst, vmm.cfg: - VMM/maillocation: Dovecot >= 2.0.beta5 is required for `doveadm - mailbox create -s …` - [217b419d6561] <v0.6.x> - -2010-07-22 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py: - VMM/Account: s/prefix/mbformat/ and pass the dbh to - MailLocation.__init__. - [504fd29b4712] <v0.6.x> - - * VirtualMailManager/maillocation.py: - VMM/maillocation: Renamed MailLocation's property prefix to - mbformat. - [3c62f581d17a] <v0.6.x> - - * VirtualMailManager/Config.py, man/de/man5/vmm.cfg.5.rst, - man/man5/vmm.cfg.5.rst, man/substitute_links_5.rst, vmm.cfg: - VMM/Config: Added boolean option mailbox.subscribe. - [df0f7b22540c] <v0.6.x> - - * VirtualMailManager/Config.py: - VMM/Config: Return mailbox.{folders,root} settings as Unicode. - [8dd3a107fd92] <v0.6.x> - -2010-07-21 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/maillocation.py: - VMM/maillocation: Reworked class MailLocation to match the new - database structure. - [32b4a39b5640] <v0.6.x> - - * VirtualMailManager/Config.py: - VMM/Config: Added function check_mailbox_format(). - [e1d3f027dd64] <v0.6.x> - -2010-07-20 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man5/vmm.cfg.5.rst: - man/de/man5/vmm.cfg.5.rst: Fixed a typo. - [efa001edc349] <v0.6.x> - - * man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst: - man/{,de/}man5/vmm.cfg.5.rst: Added mailbox.root, small updates. - [d15a27eaa9d2] <v0.6.x> - - * VirtualMailManager/Config.py, update_config.py, vmm.cfg: - VMM/Config: Added mailbox.root setting. - [ee89399346cb] <v0.6.x> - - * TODO, pgsql/create_optional_types_and_functions-dovecot-1.2.x.pgsql, - pgsql/create_optional_types_and_functions.pgsql, pgsql - /create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_tables_0.5.x-0.6.pgsql, - pgsql/update_types_and_functions_0.5.x-0.6-dovecot-1.2.x.pgsql, - pgsql/update_types_and_functions_0.5.x-0.6.pgsql: - pgsql: Added support for different mailbox formats. - - users.passwd can store sha512-crypt.hex hashes now - - Added new update scripts. - [e21ceaabe871] <v0.6.x> - -2010-07-12 Pascal Volk <neverseen@users.sourceforge.net> - - * pgsql/update_tables_0.4.x-0.5.pgsql, - pgsql/update_tables_0.5.x_for_dovecot-1.2.x.pgsql, - pgsql/update_types_and_functions_0.5.x_for_dovecot-1.2.x.pgsql: - pgsql: Removed old update SQL scripts. - [62211b6a9b8e] <v0.6.x> - -2010-07-04 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py, VirtualMailManager/maillocation.py: - VMM/maillocation: Code cleanups. Fixed error introduced with - changeset 084300a00ee1. - [18086c6a2521] <v0.6.x> - -2010-05-18 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Domain.py, VirtualMailManager/Handler.py: - VMM/Domain: removed functions ace2idna() and idn2ascii(). - domainname.encode('idna')/domainname.decode('idna') works too. - [7d1bafc6fa30] <v0.6.x> - -2010-05-12 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Handler.py: - VMM/Account: replaced attribute _mid : int by _mail : MailLocation. - [a77b67673aa6] <v0.6.x> - -2010-05-11 Pascal Volk <neverseen@users.sourceforge.net> - - * TODO, VirtualMailManager/password.py: - VMM/password: added some CRYPT_* constants. Reverted modification - (284:ec1966828246) in _get_salt(). - [619dadc0fd25] <v0.6.x> - -2010-05-10 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py, VirtualMailManager/password.py, - man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst: - VMM/password: adapted Blowfish/SHA-256/SHA-512 crypt() to recent - changes in the Dovecot-2.0 source tree. - - VMM/Config: Added default number of encryption rounds to the - configuration. - - man5: updated description of - misc.crypt_{blowfish,sha{256,512}}_rounds. - [7ef3f117a230] <v0.6.x> - -2010-05-09 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/Handler.py, VirtualMailManager/Relocated.py, - VirtualMailManager/cli/Config.py, - VirtualMailManager/ext/Postconf.py, VirtualMailManager/password.py: - VMM/…: re-indented long queries and error messages. - [e2785e04f92e] <v0.6.x> - -2010-05-05 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/password.py: - VMM/password: generate all crypt() salts w/o trailing $ sign - [142f188f7552] <v0.6.x> - -2010-05-04 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst: - man5: added misc.dovecot_version to the minimal config example. - [01cb71c1ae33] <v0.6.x> - - * VirtualMailManager/Config.py, VirtualMailManager/password.py: - VMM/password: moved the 'scheme check' code from pwhash() to the new - function verify_scheme(). VMM/Config: use verify_scheme() to check - the scheme when LazyConfig.set() is called. - [1e77dd639fa3] <v0.6.x> - -2010-05-03 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py, man/de/man5/vmm.cfg.5.rst, - man/man5/vmm.cfg.5.rst: - VMM/Config: removed the default value of misc.dovecot_version. There - are too many different versions installed on different systems. So, - it doesn't make much sense to have a default value. - [e2046d47688b] <v0.6.x> - - * VirtualMailManager/Handler.py: - VMM/Handler: import the errors before raising them. Rephrased the - 'permission error' message. - [d30a94f5aef5] <v0.6.x> - - * TODO, VirtualMailManager/Config.py, VirtualMailManager/password.py, - man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst, - man/substitute_links_5.rst: - VMM/password: Added support Blowfish/SHA-256/SHA-512 crypt(). Also - updated Config and man section 5. - [ec1966828246] <v0.6.x> - -2010-04-30 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Handler.py: - VMM/Handler: code cleanups in the user/alias/relocated info methods. - [ea6d052de24a] <v0.6.x> - - * VirtualMailManager/Handler.py: - VMM/Handler: fixed destination check in Handler.aliasAdd(). - [28871c1be260] <v0.6.x> - - * VirtualMailManager/Alias.py, VirtualMailManager/Handler.py, - VirtualMailManager/cli/Handler.py: - VMM/Alias: moved the postconf stuff from the Handlers to Alias - class. - [59ff7c719697] <v0.6.x> - - * VirtualMailManager/Config.py, VirtualMailManager/Handler.py: - VMM/{Config,Handler}: moved Config.install() to - Handler.cfg_install(). Handler.cfg_install() must be called - explicitly. To avoid 'strange' problems. - [db35d2eec518] <v0.6.x> - -2010-04-29 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/Handler.py: - VMM/cli/Handler: fixed AttributeError in CliHandler.__init__(). - Attribute '_scheme' was removed in previous commit. - [74d94b867348] <v0.6.x> - - * VirtualMailManager/Handler.py: - VMM/Handler: removed password hashing related stuff. - [5d229a50b115] <v0.6.x> - - * VirtualMailManager/Handler.py, VirtualMailManager/cli/Handler.py: - VMM{,/cli}/Handler: adjusted user* methods to the changes in - Account. All user methods was renamed from userAction() to - user_action(). Added missing docstrings. - [e50ffc0b8468] <v0.6.x> - - * VirtualMailManager/Account.py: - VMM/Account: always pass the EmailAddress to the pwhash() call. - [f2ecfe0a0e09] <v0.6.x> - - * VirtualMailManager/Account.py, - VirtualMailManager/constants/ERROR.py: - VMM/Account: some modifications and small improvements in class - Account. - - replaced the tid by a Transport instance - - check mailbox format dependencies in _repare() - - reset all attributes when the Account was deleted - - don't select information, we have already, from the db - - added __nonzero__() method - [524f7ed5ad5b] <v0.6.x> - - * VirtualMailManager/password.py: - VMM/password: added small output check on _dovecotpw(). - [45ec5c3cfef4] <v0.6.x> - - * VirtualMailManager/common.py: - VMM/common: added a caching dict for version_hex()/version_str() - [77fc7138ef6a] <v0.6.x> - -2010-04-28 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py, VirtualMailManager/Handler.py, - VirtualMailManager/__init__.py, VirtualMailManager/password.py: - VMM/Config: Added method Config.install() -> global cfg_dget(). - VirtualMailManager.Configuration removed -> some adjustments. - [446483386914] <v0.6.x> - - * INSTALL, UPGRADE: - INSTALL: dropped group mail related stuff. UPGRADE: be more details - about nobody's primary group. - [e915d4725706] <v0.6.x> - - * VirtualMailManager/Config.py, VirtualMailManager/Handler.py, - man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst, update_config.py, - vmm.cfg: - configuration: Dropped setting misc.gid_mail. That setting was never - useful, since none of the virtual users was a member of a system - group. - [d3389645a91d] <v0.6.x> - - * man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst, - man/substitute_links.rst: - man/{,de/}man5/vmm.cfg.5.rst: Updated descriptions of dovecotpw and - password_scheme settings. - [188ea8d6072f] <v0.6.x> - - * INSTALL, VirtualMailManager/password.py, - VirtualMailManager/pycompat/hashlib.py: - VMM: added new modules password and pycompat.hashlib. INSTALL: - updated - [beb8f4421f92] <v0.6.x> - - * VirtualMailManager/maillocation.py: - VMM/maillocation: Use the hex version, since we are able to convert - it to an string, in case of a failure. - [084300a00ee1] <v0.6.x> - -2010-04-27 Tobias Berling <t-obi@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Handler.py, - VirtualMailManager/common.py: - VMM/{Account,common,Handler}: Improved version_hex(). - - common: version_hex() now supports 'serials' > 16. Added - version_str() as counterpart to version_hex(). - - Account, Handler: updated hardcoded Dovecot versions. - [e14c345b44a1] <v0.6.x> - -2010-04-26 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/common.py, - VirtualMailManager/maillocation.py: - VMM/{Account,common,maillocation}: Dovecot version (check) fixes. - - Account: fixed versions dependencies. - - maillocation: use the version string, may be uses in a error - message. - - common: version_hex() raises a ValueError, instead of returning 0, - if the version string is invalid. - [3c0173418d5d] <v0.6.x> - -2010-04-25 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Config.py, - VirtualMailManager/Handler.py, VirtualMailManager/maillocation.py, - man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst, update_config.py, - upgrade.sh, vmm.cfg: - Use the complete Dovecot version, not only the concatenated major - and minor parts. (1.2.11 instead of 12). - [04fea4d8b900] <v0.6.x> - - * VirtualMailManager/common.py: - VMM/common: improved version_hex() in order to convert also alpha, - beta and release candidate versions. - [07fdc93dde9f] <v0.6.x> - -2010-04-24 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py, VirtualMailManager/Handler.py, - VirtualMailManager/__init__.py, VirtualMailManager/common.py: - VMM: moved some non-init functions to the new common module. - Adjusted imports in the Config and Handler module. - [6eea85d8b91d] <v0.6.x> - -2010-04-23 Pascal Volk <neverseen@users.sourceforge.net> - - * setup.py: - setup.py: Added sub-package pycompat to the packages list. - [1c2241dde942] <v0.6.x> - -2010-04-22 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/pycompat.py, - VirtualMailManager/pycompat/__init__.py: - VMM/pycompat: is now a sub-package. - [b052a2f0f5d4] <v0.6.x> - -2010-04-20 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Handler.py: - merged changes from default(9bf8d97ced88) - [6c699837b4d4] <v0.6.x> - - * VirtualMailManager/VirtualMailManager.py: - VMM/VMM: corrected name of password scheme PLAIN-MD4. - [9bf8d97ced88] - -2010-04-18 Tobias Berling <mail@tobiasberling.de> - - * VirtualMailManager/Alias.py, VirtualMailManager/AliasDomain.py, - pgsql/create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql: - VMM/Alias.py: Replaced some %r with '%s'. VMM/AliasDomain.py: - save(), switch(), delete(): Update AliasDomain._gid after database - change. Added dbc.close() to AliasDomain.delete(). - create_tables{,-dovecot-1.2.x}.pgsql: Fixed a typo. - [5b8fde01e4f0] <v0.6.x> - -2010-04-18 Pascal Volk <neverseen@users.sourceforge.net> - - * TODO, VirtualMailManager/Handler.py, VirtualMailManager/__init__.py: - VMM: added 'Configuration' variable and set_configuration(). - Handler.__init__() now exports its config via set_configuration(). - [ae80282301a3] <v0.6.x> - -2010-04-17 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Handler.py: - VMM/Handler: renamed some methods and added their missing - docstrings: - - cfgDget() -> cfg_dget() - - cfgPget() -> cfg_pget() - - userByID() -> user_by_uid() - [d2ddd4a6528d] <v0.6.x> - -2010-04-16 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/AliasDomain.py, VirtualMailManager/Domain.py, - VirtualMailManager/EmailAddress.py, VirtualMailManager/Handler.py, - VirtualMailManager/__init__.py: - VMM: moved functions ace2idna(), check_domainname(), idn2ascii() and - relevant parts to the Domain module. Adjusted imports in modules - AliasDomain, EmailAddress and Handler. - [8aecc83a0d32] <v0.6.x> - - * VirtualMailManager/EmailAddress.py, VirtualMailManager/__init__.py: - VMM: moved check_localpart() to the EmailAddress module. - [58d1b6f41664] <v0.6.x> - -2010-04-15 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py: - VMM/Account: renamed function getAccountByID -> get_account_by_uid. - Fixed AttributeError (tid) in Account._prepare(). Removed unused - imports. - [af555e6967c8] <v0.6.x> - - * VirtualMailManager/Handler.py: - VMM/Handler: Implemented Handler._chk_other_address_types(). Removed - the static methods accountExists(), aliasExists(), relocatedExists() - and _exists(). - [0963ad2f5fe2] <v0.6.x> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/Relocated.py: - VMM/{Account,Alias,Relocated}: added a address property to the - classes Account, Alias and Relocated. - [73cd082cd724] <v0.6.x> - - * VirtualMailManager/Relocated.py: - VMM/Relocated: implemented Relocated.__nonzero__() for truth value - testing. Use EmailAddress' __str__() method when raising - RelocatedErrors. - [bb7d9906c529] <v0.6.x> - - * INSTALL: - merged changes from default(dbcb29ac89fa) - [da241eacad4d] <v0.6.x> - - * INSTALL: - INSTALL: simplified the 'SETUID copy of deliver' part - [dbcb29ac89fa] - - * VirtualMailManager/Account.py: - VMM/Account: Account.get_info() use the domain's transport, if tid - matches. - [481280686789] <v0.6.x> - - * VirtualMailManager/Account.py, - VirtualMailManager/constants/ERROR.py: - VMM/Account: reworked class Account. - [f9a6b6701cf9] <v0.6.x> - -2010-04-13 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Handler.py: - VMM/Handler: adjusted Handler.aliasDomain*() methods to changes in - the AliasDomain class. Updated docstrings. - [698ba4208ddc] <v0.6.x> - - * VirtualMailManager/AliasDomain.py: - VMM/AliasDomain: some cleanups in class AliasDomain. Added missing - docstrings. - [30aaf2bc079c] <v0.6.x> - -2010-04-05 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Domain.py: - VMM/Domain: search() small code cleanups. - [496099847480] <v0.6.x> - - * VirtualMailManager/Handler.py: - VMM/Handler: small code cleanups and an improved import statement. - [2493453f2c10] <v0.6.x> - - * VirtualMailManager/Domain.py, VirtualMailManager/Handler.py: - merged changes from default(184970fd7486) - [fb6336b25b8f] <v0.6.x> - - * VirtualMailManager/Domain.py: - VMM/Domain: search() lists now all matching domains, also when the - result contains primary and alias names, but the found alias is not - an alias for any of the found primaries. - [184970fd7486] - - * VirtualMailManager/VirtualMailManager.py: - VMM/VMM: applied 'code compression' from v0.6.x(09b7e3fe29b3) to - VirtualMailManager.domainList(). - [8f56166a3283] - -2010-04-04 Tobias Berling <mail@tobiasberling.de> - - * VirtualMailManager/Handler.py: - VMM/Handler: compressed Handler.domainList() and replaced “%s” with - '%s' in error message. - [09b7e3fe29b3] <v0.6.x> - -2010-04-04 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/AliasDomain.py, - VirtualMailManager/Domain.py, VirtualMailManager/Handler.py: - VMM/Domain: reworked Domain class. Adjusted classes Account, - AliasDomain and Handler to changes in the Domain class. - [084331dd1e4c] <v0.6.x> - -2010-04-03 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Transport.py: - VMM/Transport: Renamed attribute/property {,_}id to {,_}tid. - [9d3405ed08e5] <v0.6.x> - -2010-04-02 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/__init__.py: - VMM: check_localpart() use '%s' instead of %r in error messages. - [e88ba0fb1281] <v0.6.x> - -2010-03-21 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Handler.py: - merged changes from default(8c4df3dd2d2c) - [55503d63ba30] <v0.6.x> - - * vmm: - vmm: minimal cleanups. - [3c766114d0b9] <v0.6.x> - - * VirtualMailManager/VirtualMailManager.py: - VMM: VirtualMailManager.__pwhash() added support for 'doveadm pw'. - dovecotpw was replaced by `doveadm pw` in Dovecot v2.0. To use - doveadm instead of dovecotpw use the following settings in vmm.cfg: - [bin] dovecotpw = /path/to/doveadm [misc] dovecotvers = - 20 - [8c4df3dd2d2c] - -2010-03-03 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst, - man/substitute_links_5.rst: - man: updated configuration manual pages (maildir.* -> mailbox.*). - [eefbe052a135] <v0.6.x> - - * VirtualMailManager/Config.py, update_config.py, vmm.cfg: - vmm.cfg: renamed maildir.folders to mailbox.folders. maildir.name - was removed. new: mailbox.format, in order to support all mailbox - formats from Dovecot. Maildir is the default format. - - Adjusted VirtualMailManager/Config and update_config.py to the - changes mentioned above. - [0fb2f12648a7] <v0.6.x> - - * VirtualMailManager/Account.py, VirtualMailManager/maillocation.py: - VMM/maillocation: MailLocation.__init__(): take a 'format' name, - instead of a 'directory' name. - - added function known_format() to the module. - - VMM/Account: Adjusted to above changes. - [a7b000ca4ac9] <v0.6.x> - -2010-03-02 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, - VirtualMailManager/constants/ERROR.py, - VirtualMailManager/maillocation.py, - doc/source/vmm_constants_error.rst: - VMM/Account: Adjusted to changes in maillocation.MailLocation. - VMM/maillocation: Class MailLocation added missing property `mid`. - - Added new error to VMM/constants/ERROR and - doc/source/vmm_constants_error - [87db9f1f95ea] <v0.6.x> - - * VirtualMailManager/MailLocation.py, - VirtualMailManager/maillocation.py, - doc/source/vmm_constants_error.rst: - VMM/maillocation: rewrote MailLocation class. Renamed - MailLocation.py to maillocation.py. - [311eee429f67] <v0.6.x> - -2010-03-01 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Domain.py, - VirtualMailManager/Transport.py: - VMM/Transport: reworked Transport class. Use assertions for argument - checks. Removed methods getID() and getTransport(). This values are - now accessible through the read-only attributes id and transport. - - VMM/{Account,Domain}: adjusted to modifications in Transport class. - A few code cleanups. - [a51809f7940b] <v0.6.x> - - * VirtualMailManager/pycompat.py: - VMM/pycompat: added function any() for Python 2.4 - [7e9874a50d92] <v0.6.x> - - * VirtualMailManager/Alias.py, VirtualMailManager/Handler.py, - VirtualMailManager/ext/Postconf.py: - replaced some "for x in list …" - [5c7b7cbb01cd] <v0.6.x> - -2010-02-28 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py, VirtualMailManager/Domain.py, - VirtualMailManager/Handler.py, VirtualMailManager/Relocated.py: - VMM/Domain: get_gid() return 0 instead of raising an Exception, if - the domain wasn't found in the database. - [d0c16e70a9fb] <v0.6.x> - -2010-02-27 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py, VirtualMailManager/Handler.py: - VMM/Alias: renamed Alias.add_destination() to add_destinations(). - Now it's possible to add one ore more destinations to the alias with - a single method call. - - VMM/Handler: adjusted Handler.aliasAdd() to the API changes of the - Alias class. Also use get_gid from the Domain module to get the gid - of a domain. We don't need complete Domain object, only the gid. - - Handler.getWarnings(): no longer return the __warnings list. Return - a copy instead and empty the Handler.__warnings list. - [371ae0b4443d] <v0.6.x> - - * doc/source/index.rst, doc/source/vmm_alias.rst, - doc/source/vmm_constants_error.rst, doc/source/vmm_relocated.rst: - doc: Added the alias documentation. - [8b8d632f0ef3] <v0.6.x> - - * VirtualMailManager/pycompat.py: - VMM/pycompat: added to the repository. Provides all() for Py24. - [0b6ce895e1dc] <v0.6.x> - - * VirtualMailManager/EmailAddress.py: - VMM/EmailAddress: implemented EmailAddress.__hash__(). So we can - have a set() of EmailAddress instances. - [84094c7fa28b] <v0.6.x> - - * VirtualMailManager/cli/__init__.py: - VMM/cli: small optimizations in the functions w_std() and w_err() - [eecd05e31517] <v0.6.x> - -2010-02-26 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/Exceptions.py, VirtualMailManager/Handler.py, - VirtualMailManager/MailLocation.py, VirtualMailManager/Relocated.py, - VirtualMailManager/Transport.py, VirtualMailManager/__init__.py, - VirtualMailManager/cli/Config.py, VirtualMailManager/cli/Handler.py, - VirtualMailManager/errors.py, VirtualMailManager/ext/Postconf.py, - doc/source/index.rst, doc/source/vmm.rst, doc/source/vmm_config.rst, - doc/source/vmm_constants_error.rst, doc/source/vmm_emailaddress.rst, - doc/source/vmm_errors.rst, doc/source/vmm_exceptions.rst, - doc/source/vmm_relocated.rst: - Moved VirtualMailManager/Exceptions to VirtualMailManager/errors. - Renamed VMM*Exception classes to *Error. No longer add the attribute - 'message' to VMMError if it doesn't exist, like in Python 2.4. It - has been deprecated as of Python 2.6. Also removed the methods - code() and msg(), the values are now accessible via the attributes - 'code' and 'msg'. - [0c8c053b451c] <v0.6.x> - -2010-02-25 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py, VirtualMailManager/Config.py, - VirtualMailManager/EmailAddress.py, VirtualMailManager/Handler.py, - VirtualMailManager/Relocated.py, VirtualMailManager/__init__.py, - VirtualMailManager/cli/Config.py, - VirtualMailManager/cli/__init__.py, - VirtualMailManager/constants/VERSION.py, - VirtualMailManager/constants/version.py, doc/source/vmm.rst, - doc/source/vmm_config.rst, doc/source/vmm_relocated.rst: - PEP-8-ified the work of the last days. - - Renamed methods in class Alias: addDestination() -> - add_destination() delDestination() -> del_destination() - getDestinations() -> get_destinations() - - Renamed methods in class Relocated: setDestination() -> - set_destination() getInfo() -> get_info() - - Renamed VMM/constants/VERSION.py -> VMM/constants/version.py - - Adjusted relevant parts of the documentation. - [33f727efa7c4] <v0.6.x> - -2010-02-24 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Exceptions.py: - VMM/Exceptions: use the inherited CTor in all VMM*Exception classes. - [84e6e898e6c5] <v0.6.x> - - * VirtualMailManager/Alias.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/Relocated.py: - VMM:/{Alias,EmailAddress,Relocated}: use assertions for argument - checks. - [1a9fee6b93bc] <v0.6.x> - - * doc/source/conf.py, doc/source/index.rst, doc/source/vmm.rst, - doc/source/vmm_constants_error.rst, doc/source/vmm_emailaddress.rst, - doc/source/vmm_exceptions.rst, doc/source/vmm_relocated.rst: - doc: extended documentation. - [77ac6f572855] <v0.6.x> - -2010-02-22 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py: - VMM/Config: LazyConfig.getboolean(), convert the value in our - getboolean. So RawConfigParser hasn't to do the whole get() stuff - again. - [0b129678cfe1] <v0.6.x> - - * .hgignore: - Added 'doc/build' to the ignored files. - [3ddb735ec9d2] <v0.6.x> - - * VirtualMailManager/Config.py, VirtualMailManager/__init__.py, - doc/Makefile, doc/source/conf.py, doc/source/index.rst, - doc/source/vmm.rst, doc/source/vmm_config.rst: - VMM{/Config}: reduced docstrings. Added doc to the repository. - [c705a9e38962] <v0.6.x> - - * VirtualMailManager/EmailAddress.py, VirtualMailManager/Handler.py, - VirtualMailManager/__init__.py: - VMM: removed unneeded/duplicated regular expression definitions - [efa1327b721f] <v0.6.x> - - * VirtualMailManager/Config.py: - VMM/Config: moved Config.sections() to class LazyConfig. No longer - import the ENCODING from VirtualMailManager, it's no longer required - in the Config module. - [95be8f62bc0c] <v0.6.x> - -2010-02-20 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py, VirtualMailManager/cli/Config.py: - VMM/Config: renamed LazyConfig's get_boolean() to getboolean(). - VMM/cli/Config: import required ConfigParser.RawConfigParser. - [da07dd944ad1] <v0.6.x> - -2010-02-13 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/__init__.py: - VMM/cli: added __init__.py to the repository. - [bc9726c9ad85] <v0.6.x> - - * VirtualMailManager/Config.py, VirtualMailManager/cli/Config.py: - VMM/{,cli/}Config: fixed imports. Small code cleanups and cosmetic. - [83938336c518] <v0.6.x> - -2010-02-12 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py: - VMM/Alias: small code cleanups and cosmetic. - [4d601240b7db] <v0.6.x> - - * VirtualMailManager/Relocated.py: - VMM/Relocated: small code cleanups and cosmetic. - [43e7c8b440da] <v0.6.x> - - * VirtualMailManager/Config.py: - VMM/Config: LazyConfigOption.__init__() cast 'default' to 'cls'. If - the default value is not None, make sure it has the proper type. - [dbb0f7ed7858] <v0.6.x> - -2010-02-11 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py: - VMM/Config: attributes of class LazyConfigOption are read-only now. - Some small code cleanups. - [983cf98d5881] <v0.6.x> - - * VirtualMailManager/AliasDomain.py, VirtualMailManager/Domain.py, - VirtualMailManager/EmailAddress.py, VirtualMailManager/__init__.py: - VMM: renamed function chk_domainname() -> check_domainname(). Moved - EmailAddress.check_localpart() -> - VirtualMailManager.check_localpart(). Some small code cleanups in - class EmailAddress. - [0684790fff7c] <v0.6.x> - -2010-02-10 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py, VirtualMailManager/Domain.py, - VirtualMailManager/Relocated.py: - VMM/Domain: added function get_gid() to the Domain module. We don't - need to load all the domain related information from the database, - when we need only the GID of a domain. For example in the Alias or - Relocated classes. - [02d467e4fbab] <v0.6.x> - - * VirtualMailManager/Handler.py, VirtualMailManager/Relocated.py: - VMM/{Relocated,Handler}: reworked Relocated class, adjusted Handler. - [d2712e8c724e] <v0.6.x> - - * VirtualMailManager/Alias.py, VirtualMailManager/Handler.py: - VMM/{Alias,Handler}: reworked Alias class, adjusted Handler class. - Handler: - - attribute _dbh is no longer private, the VMM/cli/Handler uses it - also. - - adjusted to changes in Alias and EmailAddress classes. - [65a3163bd113] <v0.6.x> - -2010-02-09 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/EmailAddress.py: - VMM/EmailAddress: reworked class EmailAddress again. The attributes - domainname and localpart are now read-only. - [05dd49fc3ea1] <v0.6.x> - - * VirtualMailManager/EmailAddress.py: - VMM/EmailAddress: reworked once more. - - moved EmailAddress.__chkLocalpart() -> __module__.check_localpart() - - renamed EmailAddress.__chkAddress() -> EmailAddress._chk_address() - - attributes domainname and localpart are no longer protected - - added missing doc strings. - [6c06edb5b2d2] <v0.6.x> - -2010-02-08 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/EmailAddress.py: - VMM/EmailAddress: rework EmailAddress class. - [a259bdeaab5c] <v0.6.x> - -2010-02-07 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Handler.py: - VMM/Handler: fixed a SyntaxError. Oops - [0854fb9f3bc5] <v0.6.x> - - * VirtualMailManager/Handler.py: - VMM/Handler: __mailDirMake() add warning for skipped mailboxes. - - domainInfo() removed old deprecated warning. - - fixed PEP8 warnings. - [db77501aeaed] <v0.6.x> - - * VirtualMailManager/Handler.py, VirtualMailManager/cli/Handler.py: - VMM/{,cli/}Handler: reverted most of cs cf1b5f22dbd2 added a cli - handler. Moved the interactive stuff from VMM/Handler to the derived - VMM/cli/Handler. - [1903d4ce97d7] <v0.6.x> - -2010-02-06 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/cli/CliConfig.py, - VirtualMailManager/cli/Config.py: - moved VMM/cli/CliConfig to VMM/cli/Config - [e63853509ad0] <v0.6.x> - - * VirtualMailManager/Config.py, VirtualMailManager/Handler.py, - VirtualMailManager/__init__.py, vmm: - VMM/Handler: __init__ accepts now a config_type ('default'||'cli'). - - fixed syntax errors, introduced with the last commit. VMM/Config: - added Config.configure() -> NotImplementedError. VMM/__init__: - install gettext global, everything depends on it. - [cf1b5f22dbd2] <v0.6.x> - - * VirtualMailManager/Config.py, VirtualMailManager/Handler.py, - VirtualMailManager/__init__.py, VirtualMailManager/cli/CliConfig.py: - VMM/{,cli/Cli}Config: Moved interactive stuff to new CliConfig - class. Renamed Config.getsections() to Config.sections(). Small - cosmetics. - [38b9a9859749] <v0.6.x> - -2010-02-05 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Handler.py, VirtualMailManager/cli/handler.py: - moved VMM/cli/handler to VMM/Handler - [18757fd45e60] <v0.6.x> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/MailLocation.py, VirtualMailManager/Relocated.py, - VirtualMailManager/Transport.py, VirtualMailManager/__init__.py, - VirtualMailManager/cli/handler.py, - VirtualMailManager/ext/Postconf.py, vmm: - VMM/*: Moved some methods from classes to modules __init__. - - Adjusted many import statements. - - Small adjustments and whitespace cosmetics in Config.py - [6e1ef32fbd82] <v0.6.x> - -2010-02-04 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/cli/handler.py: - moved VMM/VMM to VMM/cli/handler - [d0425225ce52] <v0.6.x> - -2010-02-02 Pascal Volk <neverseen@users.sourceforge.net> - - * vmm: - vmm: reworked subcommand/arguments mapping. - [eb4c73d9d0a4] <v0.6.x> - -2010-02-01 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py: - VMM/VMM: Allow version/help subcommands even with missing - configuration options. - [84811fcc3c69] <v0.6.x> - - * update_config.py: - update_config: do not add options w/ default values. remove - config.done - [866a6d679fce] <v0.6.x> - - * VirtualMailManager/Config.py, - VirtualMailManager/VirtualMailManager.py, man/de/man5/vmm.cfg.5.rst, - man/man5/vmm.cfg.5.rst, vmm: - VMM/Config: dropped option config.done - [f8279c90e99c] <v0.6.x> - -2010-01-30 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man1/vmm.1.rst, man/de/man5/vmm.cfg.5.rst, - man/man1/vmm.1.rst, man/man5/vmm.cfg.5.rst, - man/substitute_links.rst, man/substitute_links_1.rst, - man/substitute_links_5.rst, po/de.po: - man: updated documentation … - [3d09c657e9e5] <v0.6.x> - -2010-01-29 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py, po/de.po, po/vmm.pot: - po: Quick refresh - for documentation purpose. - [9480f2b15129] <v0.6.x> - -2010-01-26 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst: - man/{,de/}man5: added a note about how to use default settings. - man/de/man5: s/Abschnitt*/Sektion*/g - [ec2e1df8bb10] <v0.6.x> - -2010-01-25 Pascal Volk <neverseen@users.sourceforge.net> - - * man/de/man5/vmm.cfg.5.rst, man/man5/vmm.cfg.5.rst, vmm.cfg: - man: Added used default values to manual. - [cc0d79842fdf] <v0.6.x> - -2010-01-24 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py, - VirtualMailManager/VirtualMailManager.py, vmm: - VMM/VMM: allow configure subcommand also with missing settings. - Removed method VirtualMailManager.setupIsDone() - - VMM/Config: Config.load() added 'finally' clause. - [b241272eb1bd] <v0.6.x> - - * VirtualMailManager/Config.py, - VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/__init__.py, vmm: - VMM/Config: reworked configuration handling. Implemented - LazyConfig(RawConfigParser) and LazyConfigOption(object) Rewrote - Config class: - * use default values and added some validation stuff - * removed attributes: __VMMsections and __changes - * replaced methods __chkSections() and __chkOptions() with __chkCfg - - VMM/VMM: Adjusted to reworked Config class. - * removed attribute __cfgSections - * removed methods: cfgGetBoolean(), cfgGetInt(), cfgGetString() - * added methods: cfgDget(), cfgPget(), cfgSet() - - VMM/__init__: added function get_unicode() - - vmm: Adjusted to replaced methods in VMM/VMM. - [974bafa59330] <v0.6.x> - -2010-01-22 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py: - branch merge - [c0e2c7687dd3] <v0.6.x> - - * VirtualMailManager/Config.py: - VMM/Config: Fixed error handling of missing sections in vmm.cfg. - [6526072ec709] - - * VirtualMailManager/Config.py: - VMM/Config: Fixed error handling of missing sections in vmm.cfg. - [6f8ac86d1611] <v0.6.x> - -2010-01-18 Pascal Volk <neverseen@users.sourceforge.net> - - * TODO, man/de/man5/vmm.cfg.5, man/de/man5/vmm.cfg.5.rst, - man/man5/vmm.cfg.5, man/man5/vmm.cfg.5.rst: - man: reworded some parts. - [d9ca5c46c1fa] <v0.6.x> - - * man/de/man5/vmm.cfg.5, man/de/man5/vmm.cfg.5.rst, - man/man5/vmm.cfg.5, man/man5/vmm.cfg.5.rst: - man: updated man/{de/,}man5/vmm.cfg.5, using reStructuredText now - [a72908248153] <v0.6.x> - -2010-01-14 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py, - VirtualMailManager/VirtualMailManager.py, update_config.py, vmm, - vmm.cfg: - vmm.cfg: a few re-renamed configuration options. - - old new - -------------------------------------------------- - account.password_len -> account.password_length domain.force_del - -> domain.force_deletion misc.base_dir -> misc.base_directory - misc.dovecot_vers -> misc.dovecot_version - [fd496561acc6] <v0.6.x> - -2010-01-13 Pascal Volk <neverseen@users.sourceforge.net> - - * install.sh, update_config.py, update_config_0.4.x-0.5.py, - upgrade.sh: - update_config.py: adjusted functions stuff to renamed settings. - Finally renamed update_config_0.4.x-0.5.py to update_config.py - no - more version information in the filename. - - *.sh: removed .svn directory exclusion from find command. - [bb58aedefa3a] <v0.6.x> - - * VirtualMailManager/Config.py, - VirtualMailManager/VirtualMailManager.py, vmm, vmm.cfg: - vmm.cfg: dealt with the most overdue section/option renaming. Added - new options. Details: - - old new - ------------------------------------------------------------ - domdir.mode -> domain.directory_mode domdir.delete - -> domain.delete_directory domdir.base -> - misc.base_dir domdir -> _section domdir - deleted_ - - maildir.mode -> account.directory_mode - maildir.diskusage -> account.disk_usage maildir.delete - -> account.delete_directory - - misc.forcedel -> domain.force_del misc.passwdscheme - -> misc.password_scheme misc.dovecotvers -> - misc.dovecot_vers - - services.smtp -> account.smtp services.pop3 - -> account.pop3 services.imap -> account.imap - services.sieve -> account.sieve services - -> _section services deleted_ - - _NEW_.random_password -> account.random_password - _NEW_.password_len -> account.password_len - _NEW_.auto_postmaster -> domain.auto_postmaster - [b152ad5c7071] <v0.6.x> - -2010-01-04 Pascal Volk <neverseen@users.sourceforge.net> - - * INSTALL: - INSTALL: Adapted pgsql configuration steps to that in the wiki. - (Closes: #2922030) - [7e50e4c49ed7] <v0.6.x> - -2010-01-02 Pascal Volk <neverseen@users.sourceforge.net> - - * install.sh, upgrade.sh: - *.sh: Added --force option to python setup.py install call. - upgrade.sh: Removed old cleanup code. - [67dc18294de6] <v0.6.x> - - * setup.py: - setup.py: Fixed a UserWarning that may occur with older Python. - [1981f285f0c0] <v0.6.x> - - * COPYING, VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/Exceptions.py, - VirtualMailManager/MailLocation.py, VirtualMailManager/Relocated.py, - VirtualMailManager/Transport.py, - VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/__init__.py, - VirtualMailManager/constants/ERROR.py, - VirtualMailManager/constants/EXIT.py, - VirtualMailManager/constants/VERSION.py, - VirtualMailManager/constants/__init__.py, - VirtualMailManager/ext/Postconf.py, - VirtualMailManager/ext/__init__.py, man/de/man1/vmm.1, - man/de/man5/vmm.cfg.5, man/man1/vmm.1, man/man5/vmm.cfg.5, po/de.po, - setup.py, update_config_0.4.x-0.5.py, vmm: - Updated copyright notices to include the year 2010. Also corrected - the name of the copyright holder and updated the e-mail address. - [0ac9ef587769] - -2009-12-27 Pascal Volk <neverseen@users.sourceforge.net> - - * .hgtags: - Removed the svn-ish tag trunk - [b62aa4aabcd0] - -2009-10-23 Pascal Volk <neverseen@users.sourceforge.net> - - * create_optional_types_and_functions-dovecot-1.2.x.pgsql, - create_optional_types_and_functions.pgsql, create_tables- - dovecot-1.2.x.pgsql, create_tables.pgsql, pgsql - /create_optional_types_and_functions-dovecot-1.2.x.pgsql, - pgsql/create_optional_types_and_functions.pgsql, pgsql - /create_tables-dovecot-1.2.x.pgsql, pgsql/create_tables.pgsql, - pgsql/update_tables_0.4.x-0.5.pgsql, - pgsql/update_tables_0.5.x_for_dovecot-1.2.x.pgsql, - pgsql/update_types_and_functions_0.5.x_for_dovecot-1.2.x.pgsql, - update_tables_0.4.x-0.5.pgsql, - update_tables_0.5.x_for_dovecot-1.2.x.pgsql, - update_types_and_functions_0.5.x_for_dovecot-1.2.x.pgsql: - *.pgsql: moved to pgsql/ - [639cf4003965] - -2009-10-22 Pascal Volk <neverseen@users.sourceforge.net> - - * install.sh, pgsql-relocated_maps.cf, pgsql- - smtpd_sender_login_maps.cf, pgsql-transport.cf, pgsql- - virtual_alias_maps.cf, pgsql-virtual_gid_maps.cf, pgsql- - virtual_mailbox_domains.cf, pgsql-virtual_mailbox_maps.cf, pgsql- - virtual_uid_maps.cf, postfix/pgsql-relocated_maps.cf, postfix/pgsql- - smtpd_sender_login_maps.cf, postfix/pgsql-transport.cf, postfix - /pgsql-virtual_alias_maps.cf, postfix/pgsql-virtual_gid_maps.cf, - postfix/pgsql-virtual_mailbox_domains.cf, postfix/pgsql- - virtual_mailbox_maps.cf, postfix/pgsql-virtual_uid_maps.cf, - upgrade.sh: - Moved Postfix PostgreSQL client configuration files into the postfix - directory. - [78b6b06188d3] - - * VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/constants/ERROR.py: - VMM: Don't prompt endless for a password. Stop after 3rd failure. - [6949f6eaf26e] - -2009-10-20 Pascal Volk <neverseen@users.sourceforge.net> - - * po/vmm.pot, vmm: - vmm: plan_a_b s/address/object/ - [eb3ccf9484b3] - - * VirtualMailManager/Account.py, - VirtualMailManager/VirtualMailManager.py, po/vmm.pot, vmm: - Added comments for the Translation Project. Updated PO template. - [a849843115e9] - -2009-10-19 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Domain.py, - VirtualMailManager/EmailAddress.py, VirtualMailManager/Relocated.py, - VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/ext/Postconf.py, vmm: - Fixed some grammar errors and typos. (Reported by Clytie Siddall) - [eb866ebb9f2e] - -2009-10-11 Pascal Volk <neverseen@users.sourceforge.net> - - * po/vi.po: - Added the Vietnamese translation to the repository. Many thanks to - Clytie Siddall from the Translation Project for the work. - [6e6488722807] - -2009-09-29 Pascal Volk <neverseen@users.sourceforge.net> - - * po/nl.po: - Updated Dutch translation (translated by Erwin Poeze). - [f0386ee0c7e8] - -2009-09-10 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/__init__.py: - Ignore unsupported locale setting and silently fall back to 'C'. - [3dbee02711cd] - -2009-09-09 Pascal Volk <neverseen@users.sourceforge.net> - - * .hgtags: - Added tag vmm-0.5.2 for changeset 3e972996da7f - [350488efe67d] - - * ChangeLog, NEWS, VirtualMailManager/constants/VERSION.py, setup.py: - Released vmm-0.5.2 - [3e972996da7f] [vmm-0.5.2] - -=== 0.5.2 === -2009-09-09 Pascal Volk <neverseen@users.sourceforge.net> - - * vmm: - Improved error handling in vmm's {alias}domaininfo. - [581a5680d0ef] [tip] - -2009-09-08 Pascal Volk <neverseen@users.sourceforge.net> - - * po/nl.po, setup.py: - Added the Dutch translation to the repository. Many thanks to Erwin - Poeze from the Translation Project for the work. - [e574f5dedb60] - - * VirtualMailManager/Alias.py, vmm: - Improved error handling in vmm's {user,alias,relocated}info. Removed - some comparisons of string and Unicode. - [e3fd0b67ae50] - -2009-09-07 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py: - Alias.__init__(): Check really if the given address is not used. - [a08d78344706] - - * VirtualMailManager/Account.py: - Sort alias addresses in Account.getAliases() / vmm userinfo. - [ead2a7e9f8be] - -2009-09-05 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py: - Small optimizations in Account.getAliases() and Alias.getInfo(). - [4c6aa6c29dd7] - - * VirtualMailManager/VirtualMailManager.py: - Code cleanup/optimization in VMM's idn2ascii() and ace2idna(). - [16542519a5a8] - -2009-09-04 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Domain.py, vmm: - Reduced the mixing/concatenating of str and unicode objects. - Optimized list generation in Domain class. - [28f26f7f3d8f] - - * VirtualMailManager/__init__.py: - Small optimization in w_std()/w_err() 'avoid the dot'. - [ecd6a379e523] - -2009-09-03 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py: - Code cleanup/optimization in VirtualMailManager's __getSalt(). - [ffac064bd728] - -2009-09-02 Pascal Volk <neverseen@users.sourceforge.net> - - * po/fr.po, setup.py: - Added the French translation to the repository. Many thanks to - Dimitri Duc from the Translation Project for the work. - [7f6911bd11cd] - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/Exceptions.py, - VirtualMailManager/MailLocation.py, VirtualMailManager/Relocated.py, - VirtualMailManager/Transport.py, - VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/__init__.py, VirtualMailManager/ext/Postconf.py, - vmm: - Reorganized module import. Dropped the import of constants.VERSION, - when it wasn't really needed. Centralized the import of os, re and - locale in VirtualMailManager/__init__.py. Also moved w_std() and - w_err() from vmm to the __init__.py. - [617f27715b01] - -2009-09-01 Pascal Volk <neverseen@users.sourceforge.net> - - * vmm: - Don't crash if the date format not only consists of ASCII signs. - Added also the u stringprefix to translatable strings where it was - missing. - [fc09f657082d] - -2009-08-31 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py, - VirtualMailManager/VirtualMailManager.py, vmm: - Reorganized imports, eliminated a potential UnicodeEncodeError. - Removed double definition of function w_std() in Config class. - [fb61f64e6351] - -2009-08-25 Pascal Volk <neverseen@users.sourceforge.net> - - * INSTALL, UPGRADE: - Updated documentation - [32ad0c79a6ef] - - * VirtualMailManager/Account.py: - Fixed a Python2.4.4 SyntaxError - [6ca3d22e5dd0] - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/AliasDomain.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, VirtualMailManager/EmailAddress.py, - VirtualMailManager/MailLocation.py, VirtualMailManager/Relocated.py, - VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/ext/Postconf.py, man/de/man1/vmm.1, - man/man1/vmm.1, po/de.po, po/vmm.pot, vmm: - Replaced angle quotes by quotation marks. - [2d5c4745efec] - -2009-08-23 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py, po/de.po, po/vmm.pot: - Added a deprecated warning for managesieve. Updated translation. - [fa22bd13b4d1] - -2009-08-22 Pascal Volk <neverseen@users.sourceforge.net> - - * INSTALL, UPGRADE: - Updated documentation - [2b8154cc7ebe] - - * update_config_0.4.x-0.5.py: - avoid error message if used with version 0.5.2 - [9dca3e898ddb] - -2009-08-21 Pascal Volk <neverseen@users.sourceforge.net> - - * .hgignore, VirtualMailManager/Alias.py, po/de.po, po/vmm.pot: - Updated translation. - [4ffb50de00d5] - - * INSTALL, UPGRADE, VirtualMailManager/Account.py, - VirtualMailManager/Config.py, VirtualMailManager/Transport.py, - VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/constants/ERROR.py, - VirtualMailManager/ext/Postconf.py: - Converted VirtualMailManager and Postconf to new-style classes. A - few small cleanups. - [cf8116625866] - - * INSTALL, UPGRADE: - Updated documentation - [97a9f6dd954b] - - * update_tables_0.5.x_for_dovecot-1.2.x.pgsql: - removed GRANT statement. It's mentioned in UPGRADE - [3643a0777e77] - - * update_tables_0.5.x_for_dovecot-1.2.x.pgsql: - Removed the currently not needed WHERE clause from the VIEW. - [988b9a719929] - - * create_optional_types_and_functions-dovecot-1.2.x.pgsql, - create_tables-dovecot-1.2.x.pgsql: - Added create SQL scripts for Dovecot v1.2.x - [68af38212ff5] - - * update_tables_0.5.x_for_dovecot-1.2.x.pgsql, - update_types_and_functions_0.5.x_for_dovecot-1.2.x.pgsql: - Added update SQL scripts for Dovecot v1.2.x - [626c008a4a04] - -2009-08-20 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py, VirtualMailManager/AliasDomain.py, - VirtualMailManager/Domain.py, VirtualMailManager/MailLocation.py, - VirtualMailManager/Relocated.py: - Converted to new-style class, added __slots__. - [30abf0abf8f8] - - * VirtualMailManager/Account.py: - Converted to new-style class, added __slots__, updated queries. Use - the _uid attribute in queries whenever it is possible. - [7ccc05774118] - - * VirtualMailManager/Config.py: - Comments updated. - [928659c8ee9f] - - * VirtualMailManager/VirtualMailManager.py, - update_config_0.4.x-0.5.py: - Small code cleanups (replaced dir+'/'+file by os.path.join()). - [014335f38962] - -2009-08-19 Pascal Volk <neverseen@users.sourceforge.net> - - * update_config_0.4.x-0.5.py, upgrade.sh: - Rewrote upgrade script and config update script - [cf85d78486ce] - - * setup.py: - Updated long_description, download_url and platforms. Dropped - VirtualMailManager.constants.VERSION import - error-prone. - [c96b5768c76d] - -2009-08-18 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/EmailAddress.py: - Fixed a logical mistake in EmailAddress.__ne__() (not used), small - code cleanups. - [949c5db6447a] - - * VirtualMailManager/Account.py, - VirtualMailManager/VirtualMailManager.py, vmm: - Added sieve/managesieve switching stuff, depending on the used - Dovecot version. - [21f264a88ab2] - - * VirtualMailManager/Account.py: - Fixed a libpq.OperationalError in Account.delete() Passing only the - object's address string to the 'alias delete' query, not the whole - EmailAddress object. - [e671210b04b8] - -2009-08-17 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Config.py, - VirtualMailManager/VirtualMailManager.py, man/de/man1/vmm.1, - man/de/man5/vmm.cfg.5, man/man1/vmm.1, man/man5/vmm.cfg.5, vmm, - vmm.cfg: - Config: renamed services.managesieve to services.sieve, added - misc.dovecotvers - [e35755191ff3] - - * VirtualMailManager/Config.py: - Hopefully the final UnicodeDecodeError fix for the Config class - - Added a global w_std() function and replaced all print statements. - [d1f345f91e1c] - -2009-08-16 Pascal Volk <neverseen@users.sourceforge.net> - - * ChangeLog: - Added the essential changes since vmm-0.4. Partly reformatted. - [50ff50f5055e] - -2009-08-14 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Domain.py, VirtualMailManager/Transport.py: - Transport: converted to new-style class; Domain: query reduction - - VirtualMailManager/Transport.py: - * added: __slots__ - * implemented: __eq__(), __ne__() and __str__() - - VirtualMailManager/Domain.py (updateTransport()): - * reduced db lookups/update - [cb8b2f6a5fca] - - * VirtualMailManager/VirtualMailManager.py: - VMM: Fixed an AttributeError, caused by the last commit. Class - EmailAddress has no __dict__ anymore. - [766299a8639d] - -2009-08-13 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/EmailAddress.py: - VMM.EmailAddress: Added __slots__ aka post-sf.net-hg-update-commit - [fb88585f17fe] - -=== 0.5.1 === -2009-08-12 Pascal Volk <neverseen@users.sourceforge.net> - - * .hgtags: - Added tag vmm-0.5.1 for changeset dc98cc162c66 - [e98a0fdf1266] - - * NEWS, UPGRADE, VirtualMailManager/constants/VERSION.py: - Released vmm-0.5.1 - [dc98cc162c66] [vmm-0.5.1] - - * pgsql-relocated_maps.cf, pgsql-smtpd_sender_login_maps.cf, - pgsql-transport.cf, pgsql-virtual_alias_maps.cf, - pgsql-virtual_gid_maps.cf, pgsql-virtual_mailbox_domains.cf, - pgsql-virtual_mailbox_maps.cf, pgsql-virtual_uid_maps.cf: - Set default value of hosts to localhost - Updated comments - -2009-08-09 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py: - Replaced the last non encoded print statement. - * install.sh, upgrade.sh: - Do now strict POSIX compliant string comparison in expressions. - Fixed a typo in upgrade.sh. - * nearly all files: - Removed the subversion keywords $Date$, $Id$ and $Rev$ from all files. - -2008-12-27 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py: - Config.configure(): Eliminated another UnicodeEncodeError. - * vmm.cfg: removed single quotes around bin.postconf - Thanks to samfisch for reporting both bugs - -2008-12-23 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py: - fixed parenthesis in Config.configure() - - * setup.py: adjusted long_description - updated url to http://vmm.localdomain.org/ - - * vmm: fixed UnicodeDecodeError, that could occur with German locale - -2008-12-08 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py,VirtualMailManager/Config.py: - Added support for variable "vmm.cfg" location in - /root:/usr/local/etc:/etc - -=== 0.5 === -2008-11-26 Pascal Volk <neverseen@users.sourceforge.net> - * NEWS: - Added to repository. News (enhancements, bug fixes) for non programmers - - * VirtualMailManager/constants/VERSION.py: - Updated version from 0.5-dev to 0.5 - -2008-09-16 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/ext/Postconf.py: - Added to repository to read some Postfix settings - -2008-09-09 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Domain.py, vmm, - VirtualMailManager/VirtualMailManager.py: - Added relocated stuff - -2008-09-08 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/EmailAddress.py: - Added to repository, to simplify/reduce address validation - -2008-09-01 Pascal Volk <neverseen@users.sourceforge.net> - - * create_optional_types_and_functions.pgsql: - Added to repository, for faster database lookups - -2008-08-29 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py: - Fixed DIGEST-MD5 hash generation. - -2008-08-23 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Exceptions.py: - Fixed AttributeError in class VMMException on older Python - installations. (VMMException instance has no attribute 'message') - -2008-08-22 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Domain.py, VirtualMailManager/AliasDomain.py - VirtualMailManager/VirtualMailManager.py: - did some alias domain modifications/enhancements - - * vmm: Implemented w_std() to write encoded output to stdout - -2008-08-19 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Config.py. - VirtualMailManager/VirtualMailManager.py, vmm: - Renamed class VMMConfig -> Config - Adjusted Config import - -2008-08-16 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py, - VirtualMailManager/Domain.py: - Added alias domain stuff - -2008-08-14 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Domain.py: - adjusted to modified database layout - - * create_tables.pgsql, update_tables_0.4.x-0.5.pgsql: - modified database layout - -2008-08-07 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py: Account.getInfo() added i18n stuff - -2008-08-06 Pascal Volk <neverseen@users.sourceforge.net> - - * vmm (_getOrder): - Respect vmm.cfg/maildir/diskusage settings - - * VirtualMailManager/VirtualMailManager.py: - Adds a warning if a directory not exists: - VirtualMailManager.__getDiskUsage() - VirtualMailManager.__maildirdelete() - VirtualMailManager.__domdirdelete() - Implemented: - VirtualMailManager.__isdir() - VirtualMailManager.cfgGetBoolean() - VirtualMailManager.cfgGetInt() - VirtualMailManager.cfgGetString() - * po/vmm.pot, po/de.po: Updated - -2008-06-17 Pascal Volk <neverseen@users.sourceforge.net> - - * install.sh, upgrade.sh: fixed $MANDIR - * vmm: removed BEL escape sequences - -2008-06-11 Pascal Volk <neverseen@users.sourceforge.net> - - * install.sh: - removed verbose stuff - fixed (multilingual) man pages installation stuff - * man/man1/vmm1, man/man5/vmm.cfg.5: - moved to sub folders - -2008-05-25 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py (VirtualMailManager): - Renamed: __idn2ascii() -> idn2ascii() - __ace2idna() -> ace2idna() - Implemented domain_list() - some small code cleanups - * vmm: - Implemented domain_list() - some small code cleanups - * VirtualMailManager/Domain.py: - Implemented search() - -2008-05-18 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py, VirtualMailManager/Alias.py, - VirtualMailManager/Config.py, VirtualMailManager/Domain.py, - VirtualMailManager/MailLocation.py, VirtualMailManager/Transport.py, - VirtualMailManager/VirtualMailManager.py, po/de.po, po/vmm.pot, vmm: - completed gettext support - -2008-05-15 Pascal Volk <neverseen@users.sourceforge.net> - - * vmm.cfg: now vmm.cfg conforms to example in INSTALL. - -2008-05-13 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py, VirtualMailManager/MailLocation.py, - VirtualMailManager/Account.py, VirtualMailManager/Transport.py, - VirtualMailManager/VirtualMailManager.py, VirtualMailManager/Config.py, - VirtualMailManager/Domain.py, vmm: - Added i18n (gettext) support - * install.sh: Install message objects - -2008-05-10 Pascal Volk <neverseen@users.sourceforge.net> - - * install.sh: Should now also work on all *BSDs - -2008-05-01 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py - (VirtualMailManager.__chkenv()): - Create the base directory with correct access mode and gid, ifit does - not exist yet. - * update_config_0.3.x-0.4.py, update_tables_0.3.x-0.4.py, UPGRADE, - upgrade.sh: - removed because vmm 0.4 was released - -=== 0.4-r41 === -2008-05-01 Pascal Volk <neverseen@users.sourceforge.net> - - * create_tables.pgsql: - fixed typo in CREATE TABLE users - * install.sh, upgrade.sh: - Added again $PF_GID (was removed with r19) - -2008-04-30 Pascal Volk <neverseen@users.sourceforge.net> - - * UPGRADE: added hint for virtual_mailbox_domains in UPGRADE - -=== 0.4 === -2008-04-30 Pascal Volk <neverseen@users.sourceforge.net> - - * vmm.1, vmm.cfg.5: - Reworded some parts. - * vmm: - Added function _getOrder() for a (hopefully) better structured output - from the domaininfo, userinfo and getuser subcommands. - -2008-04-28 Pascal Volk <neverseen@users.sourceforge.net> - - * vmm.cfg: - * update_config_0.3.x-0.4.py: - * VirtualMailManager/VirtualMailManager.py: - * VirtualMailManager/Config.py: - Moved option 'base' from section 'maildir' to section 'domdir' - * VirtualMailManager/Account.py (Account._setAddr()): - Removed parameter 'address' - * VirtualMailManager/Domain.py (Domain.getAccounts(), - Domain.getAliases()): Added 'ORDER BY' clause in queries. - + setup.py: Adjusted trove classifiers. - -2008-04-21 Pascal Volk <neverseen@users.sourceforge.net> - - * create_tables.pgsql (table users): - Replaced column 'disabled' with columns smpt, pop3, imap and managesieve - * create_tables.pgsql (view dovecot_password): - updated view, added service columns smpt, pop3, imap and managesieve - * update_tables_0.3.x-0.4.py: - Updated to consider the points above mentioned - * vmm.cfg: - Added section »services« with options: smtp, pop3, imap and managesieve - * update_config_0.3.x-0.4.py, VirtualMailManager/Config.py: - Updated, to add new section »services« - * VirtualMailManager/Account.py (Account._switchState(), - Account.enable(), Account.disable(), Account.save(), Account.getInfo()), - VirtualMailManager/VirtualMailManager.py (VirtualMailManager.user_add(), - VirtualMailManager.user_disable(), VirtualMailManager.user_enable()), - vmm (usage(), user_disable(), user_enable()): - Modified, to fit new database structure - * UPGRADE, INSTALL: - Updated information - * update_tables_0.4-dev_r24.py: - Added temporary to the repository - -2008-04-18 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py: Implemented getAccountByID() - * VirtualMailManager/VirtualMailManager.py (VirtualMailManager): - * vmm: Implemented user_byID() - -2008-04-15 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py (Account.modify()): - * vmm (main): Added code for modify user's transport - * VirtualMailManager/VirtualMailManager.py: Implemented - VirtualMailManager.user_transport() - * VirtualMailManager/VirtualMailManager.py - (VirtualMailManager.domain_transport()): - * vmm: - * VirtualMailManager/Domain.py (Domain.updateTransport()): Added code to - optional force new transport for all existing accounts. - -2008-04-14 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/VirtualMailManager.py: Implemented: - VirtualMailManager.__getSalt(), VirtualMailManager.__pwCrypt(), - VirtualMailManager.__pwSHA1(), VirtualMailManager.__pwMD5() and - VirtualMailManager.__pwMD4() - updated VirtualMailManager.__pwhash() - * VirtualMailManager/constants/VERSION.py: Set Version to 0.4-dev - * INSTALL: Added hint for python-crypto, fixed user_query - -2008-04-10 Pascal Volk <neverseen@users.sourceforge.net> - - * update_tables_0.3.x-0.4.py: Replaced view dovecot_user - * create_tables.pgsql (VIEW: dovecot_user): Added extra field mail - * UPGRADE: fixed filename, hint for view permissions and user_query - * INSTALL: Replaced mail_extra_groups with mail_privileged_group, updated - user_query - -2008-04-06 Pascal Volk <neverseen@users.sourceforge.net> - - * install.sh: Removed $PF_GID - * INSTALL: Added hints for pyPgSQL and smtpd_recipient_restrictions - * update_config_0.3.x-0.4.py: - * upgrade.sh: - * UPGRADE: Added to repository - * VirtualMailManager/VirtualMailManager.py (VirtualMailManager.__init__): - Don't call VirtualMailManager.__chkenv() if vmm is started with - option configure. - * VirtualMailManager/VirtualMailManager.py (VirtualMailManager.__chkenv): - Added value for placeholder in error message. - -2008-03-05 Pascal Volk <neverseen@users.sourceforge.net> - - * create_tables.pgsql: Removed unneeded newlines from views dovecot_user and - postfix_uid - * update_tables_0.2.x-0.3.pgsql: Removed from repository - * update_tables_0.3.x-0.4.py: Added to repository - -2008-03-04 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Alias.py: - * VirtualMailManager/VirtualMailManager.py: - * vmm: Now it's possible to delete an alias with a specific destination - -2008-03-03 Pascal Volk <neverseen@users.sourceforge.net> - - * pgsql-virtual_mailbox_domains.cf: Added to repository - * INSTALL: fixed postfix docu - -2008-03-02 Pascal Volk <neverseen@users.sourceforge.net> - - * create_tables.pgsql: Added view vmm_domain_info - * VirtualMailManager/Alias.py: Removed attribute Alias._aid - Removed parameter basedir from Alias.__init__() and Alias._setAddr() - * VirtualMailManager/MailLocation.py: Fixed typo in MailLocation.__init__() - * VirtualMailManager/Account.py: Integrated Transport- and - MailLocation-stuff - Removed attributes: Account._base and Account._home - * VirtualMailManager/VirtualMailManager.py: some small fixes - * VirtualMailManager/Domain.py: Added Transport-stuff - * vmm.cfg: Added option transport in section misc - * pgsql-transport.cf: changed query for new table layout - * pgsql-smtpd_sender_login_maps.cf: added missing single quote in query - -2008-02-02 Pascal Volk <neverseen@users.sourceforge.net> - - * create_tables: Renamed table maildir to maillocation - Added transport id to table domains, for default transport - * VirtualMailManager/Transport.py: - * VirtualMailManager/MailLocation.py: Added to repository - * VirtualMailManager/constants/ERROR.py: Added error codes for MailLocation - and Transport classes - * VirtualMailManager/Exceptions.py: Added exception classes for MailLocation - and Transport - -2008-01-18 Pascal Volk <neverseen@users.sourceforge.net> - - * create_tables.pgsql: Removed unneeded sequences 'alias_id' and - 'relocated_id'. - Removed unneeded column 'id' from table 'alias' and 'relocated'. - -2008-01-15 Pascal Volk <neverseen@users.sourceforge.net> - - * create_tables.pgsql: Redesign of table layout, create separate tables for - maildir-folder and transport. Also assign transport to users not to domains - -2008-01-11 Pascal Volk <neverseen@users.sourceforge.net> - - * vmm (usage): Fixed a syntax error. - -2008-01-09 Pascal Volk <neverseen@users.sourceforge.net> - - * install.sh: Also install docs - - * VirtualMailManager/Account.py: - * VirtualMailManager/Alias.py: - * VirtualMailManager/Config.py: - * VirtualMailManager/Domain.py: - * VirtualMailManager/Exceptions.py: - * VirtualMailManager/VirtualMailManager.py: - * setup.py: - * vmm: Included global version number. - - * VirtualMailManager/constants/VERSION.py: Added to repository. - -2008-01-09 Pascal Volk <neverseen@users.sourceforge.net> - - * VirtualMailManager/Account.py: - * VirtualMailManager/Alias.py: - * VirtualMailManager/Domain.py: - * VirtualMailManager/VirtualMailManager.py: - * vmm: Replaced email with e-mail. - Corrected opening/closing quotation marks («word» -> »word«). - - * VirtualMailManager/VirtualMailManager.py: Renamed - VirtualMailManager.__chkEmailadress to - VirtualMailManager.__chkEmailAddress. - - * ChangeLog: Added to repository. - -=== 0.3.1 === -2008-01-08 Pascal Volk <neverseen@users.sourceforge.net> - - * vmm (getVMM): Fixed names names of excepted errors. - - * VirtualMailManager/VirtualMailManager.py (VirtualMailManager.__init__): - activated check for missing sections/options - - * vmm-0.3.1.tar.bz2: It's really bzip2 compressed. ;-) - diff -r 659c4476c57c -r b678a1c43027 Configure.Dovecot_2 --- a/Configure.Dovecot_2 Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,208 +0,0 @@ -# This document contains a minimal configuration for a vmm setup with -# Dovecot v2.x. -# -# You could save this file as local.conf in the dovecot configuration directory -# (commonly /etc/dovecot or /usr/local/etc/dovecot). -# When you want to use this file as your configuration file for Dovecot, make -# sure you have commented out the line "!include conf.d/*.conf". The last line -# "!include_try local.conf" is sufficient. -# -# Otherwise you have to apply the following settings to the configuration files -# in the conf.d directory. - -### -# dovecot.conf -### -protocols = imap lmtp -# uncomment if your users should be able to manage their sieve scripts -#protocols = imap lmtp sieve - -# uncomment if you want to use the quota plugin -#dict { -# quota = pgsql:/usr/local/etc/dovecot/dovecot-dict-sql.conf.ext -#} - -### -# conf.d/10-auth.conf -### -# When you set another misc.password_scheme than PLAIN or CRAM-MD5 in -# your vmm.cfg, you have to remove cram-md5 from the auth_mechanisms -# setting. -auth_mechanisms = plain login cram-md5 -passdb { - driver = sql - args = /usr/local/etc/dovecot/dovecot-sql.conf.ext -} -userdb { - driver = sql - args = /usr/local/etc/dovecot/dovecot-sql.conf.ext -} -#!include auth-system.conf.ext - -### -# conf.d/10-mail.conf -### -first_valid_gid = 70000 -first_valid_uid = 70000 -mail_access_groups = dovemail -mail_location = maildir:~/Maildir - -# uncomment if you want to use the quota plugin -#mail_plugins = quota - -### -# conf.d/10-master.conf -### - -# if you don't want to use secure imap, you have to disable the imaps listener -##service imap-login { -## inet_listener imaps { -## port = 0 -## } -##} - -service lmtp { - unix_listener /var/spool/postfix/private/dovecot-lmtp { - user = postfix - group = postfix - mode = 0600 - } -} - -service auth { - user = doveauth - unix_listener auth-userdb { - } - unix_listener /var/spool/postfix/private/dovecot-auth { - user = postfix - group = postfix - mode = 0600 - } -} - -service auth-worker { - unix_listener auth-worker { - user = doveauth - group = $default_internal_user - mode = 0660 - } - user = doveauth -} - -service dict { - unix_listener dict { - group = dovemail - mode = 0660 - } -} - -### -# conf.d/10-ssl.conf -### -# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt> -#ssl = yes - -ssl_cert = </etc/ssl/certs/dovecot.pem -ssl_key = </etc/ssl/private/dovecot.pem - -# if you want to disable SSL/TLS, you have set 'ssl = no' and disable the -# imaps listener in conf.d/10-master.conf - -### -# conf.d/15-lda.conf -### -postmaster_address = postmaster@YOUR-DOMAIN.TLD -recipient_delimiter = + -protocol lda { - # uncomment if you want to use the quota plugin - #mail_plugins = $mail_plugins - # uncomment if you want to use the quota and sieve plugins - #mail_plugins = $mail_plugins sieve -} - -### -# conf.d/20-imap.conf -### -protocol imap { - # uncomment if you want to use the quota plugin - #mail_plugins = $mail_plugins imap_quota -} - -### -# conf.d/20-lmtp.conf -### -protocol lmtp { - # uncomment if you want to use the quota plugin - #mail_plugins = $mail_plugins - # uncomment if you want to use the quota and sieve plugins - #mail_plugins = $mail_plugins sieve -} - -### -# conf.d/90-quota.conf -### -# uncomment if you want to use the quota plugin -#plugin { -# quota = dict:user:%{uid}:proxy::quota -# quota_rule = *:storage=0:messages=0 -# quota_rule2 = Trash:storage=+100M -#} - -### -# conf.d/90-sieve.conf -### -# uncomment if you want to use sieve (and maybe managesieve) -#plugin { -# recipient_delimiter = + -# sieve = ~/.dovecot.sieve -# sieve_dir = ~/sieve -#} - -############################################################################### -# end of local configuration # -############################################################################### - - -### -# etc/dovecot/dovecot-sql.conf.ext -### -# apply this settings to your dovecot-sql.conf.ext - -#driver = pgsql -#connect = host=localhost dbname=mailsys user=dovecot password=$Dovecot_PASS -# -#password_query = \ -# SELECT userid AS "user", password FROM dovecotpassword('%Ln', '%Ld') WHERE %Ls -# -## uncomment this user_query if you want to use the quota plugin -#user_query = \ -# SELECT home, uid, gid, mail, quota_rule FROM dovecotquotauser('%Ln', '%Ld') -## otherwise uncomment the following user_query -#user_query = SELECT home, uid, gid, mail FROM dovecotuser('%Ln', '%Ld') -# -#iterate_query = \ -# SELECT local_part AS username, domain_name.domainname AS domain \ -# FROM users \ -# LEFT JOIN domain_data USING (gid) \ -# LEFT JOIN domain_name USING (gid) - - -### -# etc/dovecot/dovecot-dict-sql.conf.ext -### -# if you want to use the quota plugin add this lines to your -# dovecot-dict-sql.conf.ext - -#connect = host=localhost dbname=mailsys user=dovecot password=$Dovecot_PASS -#map { -# pattern = priv/quota/storage -# table = userquota -# username_field = uid -# value_field = bytes -#} -#map { -# pattern = priv/quota/messages -# table = userquota -# username_field = uid -# value_field = messages -#} diff -r 659c4476c57c -r b678a1c43027 INSTALL --- a/INSTALL Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -Installation Prerequisites -You should already have installed and configured Postfix, Dovecot and -PostgreSQL. - -The Virtual Mail Manager depends on: - - Python (>= 2.4.0) - - Psycopg 2¹ or pyPgSQL² - -If you are using Python <= 2.5.0: - - if you want to store your users' passwords as PLAIN-MD4 digest in - the database, vmm will try to use Crypto.Hash.MD4 from PyCrypto³. - - if you are using Dovecot >= v1.1.0 and you want to store your users' - passwords as SHA256 or SSHA256 hashes, vmm will try to use - Crypto.Hash.SHA256 from PyCrypto². For SHA256/SSHA256 you should have - at least use PyCrypto in version 2.1.0alpha1. - - When the Crypto.Hash module couldn't be imported, vmm will use - dovecotpw/doveadm, if the misc.password_scheme setting in the vmm.cfg - is set to PLAIN-MD4, SHA256 or SSHA256 - -[1] Psycopg: <http://initd.org/psycopg/> (Debian: python-psycopg2) -[2] pyPgSQL: <http://pypgsql.sourceforge.net/> (Debian: python-pgsql) -[3] PyCrypto: <http://www.pycrypto.org/> (Debian: python-crypto) - - -Create additionally a user and groups for improved security - We will create the system user `doveauth'. This user is used in the - authentication process. On a Debian GNU/Linux System use this command: - - adduser --system --home /nonexistent --no-create-home --group \ - --disabled-login --gecos "Dovecot IMAP/POP3 authentication user" \ - doveauth - - This will create the doveauth user and group. - For Dovecot >= 2.0 we create also the group `dovemail'. Dovecot will assign - this group to all Dovecot processes. - On a Debian GNU/Linux bases system run: - - addgroup --system dovemail - - -Configuring PostgreSQL -(for more details see: - http://vmm.localdomain.org/installation/postgresql_configuration.html) - -* /etc/postgresql/8.4/main/pg_hba.conf - [ if you prefer to connect via TCP/IP ] - # IPv4 local connections: - host mailsys +mailsys 127.0.0.1/32 md5 - [ if you want to connect through a local Unix-domain socket ] - # "local" is for Unix domain socket connections only - local mailsys +mailsys md5 - - # reload configuration - /etc/init.d/postgresql-8.4 force-reload - -* Create a database superuser if necessary: - # as root run: su - postgres - # if you have sudo privileges run: sudo su - postgres - # create your superuser, which will be able to create users and databases - createuser -s -d -r -E -e -P $USERNAME - -* As superuser create the database and db users for vmm, Postfix and Dovecot - connecting to PostgreSQL: - psql template1 - - # create users, group and the database - CREATE ROLE vmm LOGIN ENCRYPTED PASSWORD 'DB PASSWORD for vmm'; - CREATE ROLE dovecot LOGIN ENCRYPTED password 'DB PASSWORD for Dovecot'; - CREATE ROLE postfix LOGIN ENCRYPTED password 'DB PASSWORD for Postfix'; - CREATE ROLE mailsys WITH USER postfix, dovecot, vmm; - CREATE DATABASE mailsys WITH OWNER vmm ENCODING 'UTF8'; - \q - - # connect to the new database - psql mailsys vmm -W -h 127.0.0.1 - # either import the database structure for Dovecot v1.0.x/v1.1.x - \i vmm-y.x.z/pgsql/create_tables.pgsql - # or import the database structure for Dovecot v1.2.x/v2.x - \i vmm-x.y.z/pgsql/create_tables-dovecot-1.2.x.pgsql - # leave psql - \q - - # set permissions for your Dovecot and Postfix users - # see python set-permissions.py -h for details - python vmm-x.y.z/pgsql/set-permissions.py -a -H 127.0.0.1 -U vmm - -Create directory for your mails - mkdir /srv/mail - cd /srv/mail/ - mkdir 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z - chmod 771 /srv/mail - chmod 751 /srv/mail/* - - -For Dovecot >= 2.0 read the file Configure.Dovecot_2 -Configuring Dovecot v1.x - -* /etc/dovecot/dovecot.conf - # all your other settings - #disable_plaintext_auth = no - mail_location = maildir:~/Maildir - first_valid_uid = 70000 - first_valid_gid = 70000 - protocol lda { - postmaster_address = postmaster@YOUR-DOMAIN.TLD - } - auth default { - mechanisms = cram-md5 login plain - passdb sql { - args = /etc/dovecot/dovecot-sql.conf - } - userdb sql { - args = /etc/dovecot/dovecot-sql.conf - } - user = doveauth - socket listen { - master { - path = /var/run/dovecot/auth-master - mode = 0600 - } - client { - path = /var/spool/postfix/private/dovecot-auth - mode = 0660 - user = postfix - group = postfix - } - } - } - -* /etc/dovecot/dovecot-sql.conf - driver = pgsql - connect = host=localhost dbname=mailsys user=dovecot password=$Dovecot_PASS - default_pass_scheme = CRAM-MD5 - password_query = SELECT userid AS "user", password FROM dovecotpassword('%Ln', '%Ld') WHERE %Ls - user_query = SELECT home, uid, gid, mail FROM dovecotuser('%Ln', '%Ld') - -Provide a root SETUID copy of Dovecot's deliver agent for Postfix - -/!\ Only required with Dovecot v.1.x. - With Dovecot >= v2.0 use Dovecot's lmtp! - - mkdir -p /usr/local/lib/dovecot - chmod 700 /usr/local/lib/dovecot - chown nobody /usr/local/lib/dovecot - cp /usr/lib/dovecot/deliver /usr/local/lib/dovecot/ - chown root:`id -g nobody` /usr/local/lib/dovecot/deliver - chmod u+s,o-rwx /usr/local/lib/dovecot/deliver - - - -Start or restart Dovecot - - -Configuring Postfix's master.cf - -/!\ Only required with Dovecot v.1.x. - # Add Dovecot's deliver agent - dovecot unix - n n - - pipe - flags=DORhu user=nobody argv=/usr/local/lib/dovecot/deliver -f ${sender} - -d ${user}@${nexthop} -n -m ${extension} - - - -Configuring Postfix's main.cf - sql = pgsql:${config_directory}/ - proxysql = proxy:${sql} - - # relocated users from the database - #relocated_maps = ${proxysql}pgsql-relocated_maps.cf - - # transport settings from our database - transport_maps = ${proxysql}pgsql-transport_maps.cf - - # virtual domains - virtual_mailbox_domains = ${proxysql}pgsql-virtual_mailbox_domains.cf - virtual_alias_maps = ${proxysql}pgsql-virtual_alias_maps.cf - virtual_minimum_uid = 70000 - virtual_uid_maps = ${sql}pgsql-virtual_uid_maps.cf - virtual_gid_maps = ${sql}pgsql-virtual_gid_maps.cf - virtual_mailbox_base = / - virtual_mailbox_maps = ${proxysql}pgsql-virtual_mailbox_maps.cf - - # dovecot LDA (only recommended with Dovecot v1.x) - #dovecot_destination_recipient_limit = 1 - #virtual_transport = dovecot: - - # dovecot lmtp - virtual_transport = lmtp:unix:private/dovecot-lmtp - - # dovecot SASL - smtpd_sasl_type = dovecot - smtpd_sasl_path = private/dovecot-auth - smtpd_sasl_auth_enable = yes - # Keep smtpd_sasl_local_domain identical to Dovecot's auth_default_realm: - # empty. Both are empty by default. Let it commented out. - # Read more at: http://wiki.dovecot.org/Authentication/Mechanisms/DigestMD5 - #smtpd_sasl_local_domain = - smtpd_sasl_security_options = noplaintext, noanonymous - #smtpd_sasl_security_options = noanonymous - #broken_sasl_auth_clients = yes - - smtpd_recipient_restrictions = - permit_mynetworks - permit_sasl_authenticated - reject_unauth_destination - - -Installing the Virtual Mail Manager and configure the rest - - Installing from Mercurial or vmm-x.y.z.tar.gz - after cloning from the hg repo or extracting the archive change into the - new directory and type: - ./install.sh - edit all the pgsql-*.cf files in /etc/postfix - - reload postfix - - # configure the Virtual Mail Manager - # vmm.cfg(5) - configuration file for vmm - # - # For Dovecot v1.x use 'dovecot:' as domain.transport - # When using Dovecot v2.x use 'lmtp:unix:private/dovecot-lmtp' as - # domain.transport - vmm configure - - # for help type - # vmm(1) - command line tool to manage email domains/accounts/aliases - vmm help - diff -r 659c4476c57c -r b678a1c43027 NEWS --- a/NEWS Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -v0.6.2 2014-02-01 Pascal Volk <user+vmm@localhost.localdomain.org> - - * Added support for ccTLDs and 'new' gTLDs - * Added support for SCRAM-SHA-1 password hashes (Dovecot ≧ v2.2.0) - * Updated translations: Finnish - - Fixed a TypeError in `userdelete … force` - - Fixed an error in the install.sh script - -v0.6.1 2012-10-03 Pascal Volk <user+vmm@localhost.localdomain.org> - - * Added help messages for `vmm help <subcommand>` - * Updated translations: Dutch - + aliasinfo: Print list of destinations sorted. - + aliasdelete, catchalldelete: Accept multiple destinations. - + Improved 'address searching' (by Martin F. Krafft). - + Added file pgsql/dovecot_update_v1.2+.pgsql. Use this if you are - upgrading your old Dovecot installation to v1.2.0 or newer. - - Fixed UnicodeDecodeErrors which may occur with some locales. - - `user{quota,services,transport} … domain` didn't work as expected. - - Fixed pgsql FUNCTION dovecotpassword() for Dovecot < v1.2.0. - (see UPGRADE for instructions how to fix the last both problems) - -v0.6.0 2012-06-28 Pascal Volk <user+vmm@localhost.localdomain.org> - - * Now vmm supports Dovecot v.2.0.x and v2.1.x - * Added support for Psycopg 2 - * Added support for Blowfish-, SHA-256- and SHA-512-crypt password - hashes. Works also with Dovecot < v2.0.x. - New subcommand: listpwschemes - * Added support for PostgreSQL-based dictionary quota limits per user. - Configurable globally and per domain. New commands: domainquota and - userquota. (Requires Dovecot >= v1.1.2) - * Command aliasadd accepts multiple destinations. - * Command domainadd can automatically create a postmaster account. - * Command useradd can generate random passwords. - * Notes can be assigned to domains and accounts (by Martin F. Krafft). - New subcommands domainnote and usernote. - * The subcommands userenable and userdisable have been replaced by - userservices. It is now also possible to enable/disable services per - domain with the additional subcommand domainservices. - * New translation: Vietnamese - + Catch-all support (by Martin F. Krafft) New subcommands: catchalladd, - catchalldelete and catchallinfo. - + Interpolated alias destinations (by Martin F. Krafft). For example: - The alias postmaster@example.org → postmaster+%d@admin.example.org - will forward mails addressed to postmaster@example.org to - postmaster+example.org@admin.example.org. - + New subcommands: configget and configset. - + New subcommands by Martin F. Krafft: listaddresses, listaliases, - listrelocated and listusers - + Added support for Dovecot's own high-performance mailbox formats - single- and multi-dbox. - - Fixed Python 2.6 DeprecationWarnings - - Command domaindelete replaced keywords 'delalias', 'deluser' and - 'delall' by the keyword 'force'. - - Command listdomains lists now all matching domains, also when the - result contains primary and alias names, but the found alias is not - alias for any of the found primaries. - - Commands userenable/userdisable accept multiple service names. The - keyword 'all' has been removed. - - Command userdelete replaced keyword 'delalias' by 'force'. - -v0.5.2 2009-09-09 Pascal Volk <neverseen@users.sf.net> - - * Now vmm supports Dovecot v1.2.x. - * vmm.cfg: renamed services.managesieve to services.sieve, added - misc.dovecotvers. - * New translations: Dutch and French. - + Improved error handling for the domaininfo, aliasdomaininfo, userinfo, - aliasinfo and relocatedinfo subcommands. - + Sorted alias listing in userinfo output. - + Reduction of useless database lookups/updates. - + Partly improved database lookups. - - Fixed a libpq.OperationalError in Account.delete(). - - Eliminated hopefully finally all (potential) UnicodeDecodeErrors. - -v0.5.1 2009-08-12 Pascal Volk <neverseen@users.sf.net> - - + Added support for a variable "vmm.cfg" location in - /root, /usr/local/etc or /etc (see vmm.cfg(5)) - - fixed a few UnicodeDecodeErrors - - fixed a quoting mistake in vmm.cfg - -v0.5 2008-11-26 Pascal Volk <neverseen@users.sf.net> - - + gettext i18n support (German translation) - + support for alias domains (add/info/switch/delete). - + support for relocated users (add/info/delete). - + base layout of the users Maildir is now configurable. Also a according - "subscriptions" file will be created. - + subcommand »listdomains«: lists all configured domains or domains that - matches the specified search pattern. - + subcommand »userinfo« can additional display assigned alias addresses. - + subcommand »aliasadd« checks Postfix's "virtual_alias_recursion_limit" - before adding an additional destination address. - + optional SQL functions (see create_optional_types_and_functions.pgsql) - - »useradd«/»userpassword«: fixed behavior of interactive password - prompt. - - fixed some encoding problems (UnicodeEncodeErrors). - - fixed bug in generation of DIGEST-MD5 hashes. diff -r 659c4476c57c -r b678a1c43027 README --- a/README Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -.. -*- restructuredtext -*- - -============================ -vmm - a virtual mail manager -============================ - -Welcome to vmm! - -**vmm** is the easy to use and configurable command line tool for -administrators and postmasters, to manage domains, alias-domains, accounts and -relocated mail users. It allows the fast and easy management of mail servers. - -vmm is written in Python_. It's designed for installations using Dovecot_ and -Postfix_ with a PostgreSQL_ backend. - -Features -======== -• General features - - ‣ Unicode/UTF-8 capable (input/storage/output) - ‣ supports IDN_ (also ccTLDs/ccIDNs and 'new' gTLDs) - ‣ supports the mailbox format Maildir_ and Dovecot's own high-performance - mailbox formats single- and multi-\ dbox_ - ‣ configurable basic mailbox structure, including sub-mailboxes - ‣ multilingual — currently: - - * Dutch - * English - * Finnish - * French - * German - * Vietnamese - -• Domain features - - ‣ configurable transport_ setting per domain - ‣ unique group identifier (GID) per domain - ‣ each domain may have one or more alias domain names - ‣ activate or deactivate services (SMTP, POP3, IMAP and ManageSieve) for new - or all accounts of a domain - ‣ configurable quota limits (size and/or number of messages) for the - domain's accounts - ‣ supports relocated_ users - ‣ the postmaster account can be created automatically when a new domain is - created - ‣ supports per-domain catch-all aliases - -• Alias domain features - - ‣ alias domain names can be switched between domains - -• Account features - - ‣ configurable transport per account - ‣ activate or deactivate one/more/all services (SMTP, POP3, IMAP and - ManageSieve) per account - ‣ configurable quota limit (size and/or number of messages) per user - ‣ per-account configuration overrides defaults defined by the domain, - otherwise the setting is inherited - ‣ unique user identifier (UID) per user - -• Alias features - - ‣ supports multiple destinations per e-mail alias - ‣ destinations can be deleted separately - ‣ destinations can be interpolated using the original address' local-part - and domain, allowing aliases to have different meaning in alias domains, - e.g. with the following defined in example.org:: - - postmaster@example.org → postmaster+%d@admin.example.org - - If example.com is an alias domain of example.org, the alias will become:: - - postmaster@example.org → postmaster+example.org@admin.example.org - postmaster@example.com → postmaster+example.com@admin.example.org - -Installation Prerequisites -========================== -You already should have installed and configured Postfix and Dovecot with -PostgreSQL support. You also need access to a local or remote PostgreSQL -server. - -To verify that your Dovecot and Postfix installation has support for -PostgreSQL use the ``postconf`` and ``dovecot`` commands as shown below:: - - hostname ~ # postconf -m | grep pgsql - pgsql - hostname ~ # postconf -a | grep dovecot - dovecot - hostname ~ # dovecot --build-options | grep postgresql - SQL drivers: mysql postgresql sqlite - -vmm depends on Python (≥ 2.4.0) and Psycopg_ (≥ 2.0) or pyPgSQL_ (≥ 2.5.1). -Psycopg and pyPgSQL are depending on parts of the *eGenix.com mx Base -Distribution* (mxDateTime_ and mxTools_). - -If you are using Python ≤ 2.5.0: - - • if you want to store your users' passwords as ``PLAIN-MD4`` digest in the - database, vmm will try to use ``Crypto.Hash.MD4`` from PyCrypto_ - • if you are using Dovecot ≥ v1.1.0 and you want to store your users' - passwords as ``SHA256`` or ``SSHA256`` hashes, vmm will try to use - ``Crypto.Hash.SHA256`` from PyCrypto. For ``SHA256``/``SSHA256`` you - should have installed PyCrypto, at least in version 2.1.0alpha1. - - When the Crypto.Hash module couldn't be imported, vmm will use - dovecotpw/doveadm, if the *misc.password_scheme* setting in your *vmm.cfg* - is set to ``PLAIN-MD4``, ``SHA256`` or ``SSHA256``. - -Source code -=========== -vmm's source code is available from the Mercurial_ repositories: - -• main repository - - ‣ ``http://hg.localdomain.org/vmm`` - -• mirror repositories - - ‣ ``https://bitbucket.org/pvo/vmm`` - ‣ ``http://hg.code.sf.net/p/vmm/code`` - -The Debian project is hosting the Git repository of vmm: - -• ``git://anonscm.debian.org/collab-maint/vmm.git`` - -Released versions are also available as gzip compressed tar archives at: -https://sourceforge.net/projects/vmm/files/vmm/ - -Installation/Upgrade -==================== -For installation or upgrading instructions read the `INSTALL` or `UPGRADE` -file. - -License -======= -In short: "**New BSD License**" aka "3-clause license". For a few more -details see the `COPYING` file. - -.. External references -.. _dbox: http://wiki2.dovecot.org/MailboxFormat/dbox -.. _Dovecot: http://dovecot.org/ -.. _IDN: http://en.wikipedia.org/wiki/Internationalized_domain_name -.. _Maildir: http://wiki2.dovecot.org/MailboxFormat/Maildir -.. _Mercurial: http://mercurial.selenic.com/ -.. _mxDateTime: http://www.egenix.com/products/python/mxBase/mxDateTime/ -.. _mxTools: http://www.egenix.com/products/python/mxBase/mxTools/ -.. _Postfix: http://www.postfix.org/ -.. _PostgreSQL: http://www.postgresql.org/ -.. _Psycopg: http://initd.org/psycopg/ -.. _PyCrypto: http://www.pycrypto.org/ -.. _pyPgSQL: http://pypgsql.sourceforge.net/ -.. _Python: http://www.python.org/ -.. _relocated: http://www.postfix.org/relocated.5.html -.. _transport: http://www.postfix.org/transport.5.html diff -r 659c4476c57c -r b678a1c43027 TODO --- a/TODO Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -- Aliases - - avoid looping aliases - -- Domain - - optional limits for number of: - + accounts - + aliases - + destinations/alias - + alias domains - -Database: - public.users.digestmd5: add "character varying(48)" - Outlook will love it. (`doveadm pw -s DIGEST-MD5.hex -p 1 -u 0`) - -- Non-root usage [madduck@madduck.net]: - - Provide /usr/share/vmm/vmm-{mkdirs,rmdirs,du} setuid wrappers that do - precisely what they have to and no more. The should probably even call - /usr/share/vmm/vmm-wrapper-helper as unprivileged user to parse the - arguments, match them with the database and obtain the actual data to - process, e.g. email@add.ress → home directory mapping from the DB, or - obtaining the set of precreatable maildirs from the config. - - - configset and configure need root, it is questionable whether these - can/should be wrapped, as they will be disabled anyway for Debian, and - they are root-like activities (unlike day-to-day postmaster work). - - - Pascal suggested to use hooks: - 07 23:36 <Faxe> zwei config settings handle_dir in domain und account - 07 23:37 <Faxe> und dann post-{domain,user}add scripte, die den wrapper aufrufen - -- relay_domains management [madduck@madduck.net]: - - should be in a separate table - -- default aliases [madduck@madduck.net] - - it should be possible to define a set of default aliases and their - destinations for a domain, e.g. postmaster@ and abuse@. For most - flexibility, there ought to be a m:n table connecting domains to sets of - default aliases. These aliases then get treated like normal aliases - unless they are overridden by a real alias. diff -r 659c4476c57c -r b678a1c43027 UPGRADE --- a/UPGRADE Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -If you still have installed vmm 0.4.x you have to proceed this step first: - - * upgrade your vmm installation to version 0.5.2 - - -If you have installed vmm 0.5.2 you have to proceed this steps: - - * stop Postfix and Dovecot - * backup/dump your database. - * backup/dump your database! - - * start psql and connect to the appropriate database - (ex. psql mailsys vmm -W -h 127.0.0.1) - * update the database, - - Dovecot < 1.2.0 - \i vmm-x.y.z/pgsql/update_tables_0.5.x-0.6.pgsql - - Dovecot >= 1.2.0, 2.0.0 and 2.1.0 - \i vmm-x.y.z/pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql - * Set database permissions. - (see python set-permissions.py -h for details) - python vmm-x.y.z/pgsql/set-permissions.py -a -H 127.0.0.1 -U vmm - - - /!\ Important note /!\ - - All the views (dovecot_* and postfix_*) have been replaced by database - functions. So you have to adjust all your postfix/pgsql-*.cf files and - also your /etc/dovecot/dovecot-sql.conf or - /etc/dovecot/dovecot-sql.conf.ext. - (See the vmm-x.y.z postfix/pgsql-*.cf files and INSTALL/Configure.Dovecot_2 - files for the new query.) - - - * execute upgrade.sh - This will also upgrade your vmm.cfg and apply the following modifications: - - old new - ------------------------------------------------------------ - domdir.mode -> domain.directory_mode - domdir.delete -> domain.delete_directory - domdir.base -> misc.base_directory - domdir -> _section domdir deleted_ - - maildir.mode -> account.directory_mode - maildir.diskusage -> account.disk_usage - maildir.delete -> account.delete_directory - maildir.folders -> mailbox.folders - maildir.name -> mailbox.root - maildir -> _section maildir deleted_ - - misc.forcedel -> domain.force_deletion - misc.transport -> domain.transport - misc.passwdscheme -> misc.password_scheme - misc.dovecotvers -> misc.dovecot_version (12 -> 1.2.11) - misc.gid_mail -> /dev/null - - services.smtp -> domain.smtp - services.pop3 -> domain.pop3 - services.imap -> domain.imap - services.sieve -> domain.sieve - services -> _section services deleted_ - - _NEW_.random_password -> account.random_password - _NEW_.password_length -> account.password_length - _NEW_.auto_postmaster -> domain.auto_postmaster - _NEW_.quota_bytes -> domain.quota_bytes - _NEW_.quota_messages -> domain.quota_messages - _NEW_.module -> database.module - _NEW_.port -> database.port - _NEW_.sslmode -> database.sslmode - _NEW_.format -> mailbox.format - _NEW_.crypt_blowfish_rounds -> misc.crypt_blowfish_rounds - _NEW_.crypt_sha256_rounds -> misc.crypt_sha256_rounds - _NEW_.crypt_sha512_rounds -> misc.crypt_sha512_rounds - - config.done -> /dev/null - config -> _section config deleted_ - - - * start Dovecot and Postfix again - - -If you have installed vmm 0.6.0 you have to proceed this steps: - - * Database fixes: - - Due to an error in usertransport's argument parsing, it is - possible that some users' transport-ID points to the erroneous - transport 'domain'. To fix that error in your database, execute - the following SQL statement: - - UPDATE users SET tid = NULL - WHERE tid = (SELECT tid FROM transport WHERE transport = 'domain'); - - - If you are using Dovecot < v1.2.0: - You have to replace the database FUNCTION dovecotpassword(). - (see file: pgsql/create_tables.pgsql) - The service_set.ssid was selected unconditionally. This may cause - an empty result, which will make logins impossible. - - * execute upgrade.sh - - -If you have installed vmm 0.6.1 you simply have to: - - * execute upgrade.sh - -else - * read INSTALL diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/__init__.py --- a/VirtualMailManager/__init__.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager - ~~~~~~~~~~~~~~~~~~ - - VirtualMailManager package initialization code -""" - -import gettext -import locale -import sys - -from VirtualMailManager.constants import __author__, __date__, __version__ - -__all__ = [ - # version information from VERSION - '__author__', '__date__', '__version__', - # defined stuff - 'ENCODING', -] - - -# Try to set all of the locales according to the current -# environment variables and get the character encoding. -try: - locale.setlocale(locale.LC_ALL, '') -except locale.Error: - sys.stderr.write('warning: unsupported locale setting - ' - 'that may cause encoding problems.\n\n') - locale.setlocale(locale.LC_ALL, 'C') -ENCODING = locale.nl_langinfo(locale.CODESET) - -gettext.install('vmm', '/usr/local/share/locale', unicode=1) diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/account.py --- a/VirtualMailManager/account.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,498 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.account - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's Account class to manage e-mail accounts. -""" - -from VirtualMailManager.common import version_str, \ - format_domain_default -from VirtualMailManager.constants import \ - ACCOUNT_EXISTS, ACCOUNT_MISSING_PASSWORD, ALIAS_PRESENT, \ - INVALID_ARGUMENT, INVALID_MAIL_LOCATION, NO_SUCH_ACCOUNT, \ - NO_SUCH_DOMAIN, VMM_ERROR -from VirtualMailManager.common import validate_transport -from VirtualMailManager.domain import Domain -from VirtualMailManager.emailaddress import EmailAddress -from VirtualMailManager.errors import VMMError, AccountError as AErr -from VirtualMailManager.maillocation import MailLocation -from VirtualMailManager.password import pwhash -from VirtualMailManager.quotalimit import QuotaLimit -from VirtualMailManager.transport import Transport -from VirtualMailManager.serviceset import ServiceSet - -__all__ = ('Account', 'get_account_by_uid') - -_ = lambda msg: msg -cfg_dget = lambda option: None - - -class Account(object): - """Class to manage e-mail accounts.""" - __slots__ = ('_addr', '_dbh', '_domain', '_mail', '_new', '_passwd', - '_qlimit', '_services', '_transport', '_note', '_uid') - - def __init__(self, dbh, address): - """Creates a new Account instance. - - When an account with the given *address* could be found in the - database all relevant data will be loaded. - - Arguments: - - `dbh` : pyPgSQL.PgSQL.Connection - A database connection for the database access. - `address` : VirtualMailManager.EmailAddress.EmailAddress - The e-mail address of the (new) Account. - """ - if not isinstance(address, EmailAddress): - raise TypeError("Argument 'address' is not an EmailAddress") - self._addr = address - self._dbh = dbh - self._domain = Domain(self._dbh, self._addr.domainname) - if not self._domain.gid: - # TP: Hm, what “quotation marks” should be used? - # If you are unsure have a look at: - # http://en.wikipedia.org/wiki/Quotation_mark,_non-English_usage - raise AErr(_(u"The domain '%s' does not exist.") % - self._addr.domainname, NO_SUCH_DOMAIN) - self._uid = 0 - self._mail = None - self._qlimit = None - self._services = None - self._transport = None - self._note = None - self._passwd = None - self._new = True - self._load() - - def __nonzero__(self): - """Returns `True` if the Account is known, `False` if it's new.""" - return not self._new - - def _load(self): - """Load 'uid', 'mid', 'qid', 'ssid', 'tid' and 'note' from the - database and set _new to `False` - if the user could be found. """ - dbc = self._dbh.cursor() - dbc.execute('SELECT uid, mid, qid, ssid, tid, note FROM users ' - 'WHERE gid = %s AND local_part = %s', - (self._domain.gid, self._addr.localpart)) - result = dbc.fetchone() - dbc.close() - if result: - self._uid, _mid, _qid, _ssid, _tid, _note = result - - def load_helper(ctor, own, field, dbresult): - # Py25: cur = None if own is None else getattr(own, field) - if own is None: - cur = None - else: - cur = getattr(own, field) - if cur != dbresult: - kwargs = {field: dbresult} - if dbresult is None: - return dbresult - else: - return ctor(self._dbh, **kwargs) - - self._qlimit = load_helper(QuotaLimit, self._qlimit, 'qid', _qid) - self._services = load_helper(ServiceSet, self._services, 'ssid', - _ssid) - self._transport = load_helper(Transport, self._transport, 'tid', - _tid) - self._mail = MailLocation(self._dbh, mid=_mid) - self._note = _note - self._new = False - - def _set_uid(self): - """Set the unique ID for the new Account.""" - assert self._uid == 0 - dbc = self._dbh.cursor() - dbc.execute("SELECT nextval('users_uid')") - self._uid = dbc.fetchone()[0] - dbc.close() - - def _prepare(self, maillocation): - """Check and set different attributes - before we store the - information in the database. - """ - if maillocation.dovecot_version > cfg_dget('misc.dovecot_version'): - raise AErr(_(u"The mailbox format '%(mbfmt)s' requires Dovecot " - u">= v%(version)s.") % { - 'mbfmt': maillocation.mbformat, - 'version': version_str(maillocation.dovecot_version)}, - INVALID_MAIL_LOCATION) - transport = self._transport or self._domain.transport - validate_transport(transport, maillocation) - self._mail = maillocation - self._set_uid() - - def _update_tables(self, column, value): - """Update various columns in the users table. - - Arguments: - - `column` : basestring - Name of the table column. Currently: qid, ssid and tid - `value` : long - The referenced key - """ - if column not in ('qid', 'ssid', 'tid'): - raise ValueError('Unknown column: %r' % column) - dbc = self._dbh.cursor() - dbc.execute('UPDATE users SET %s = %%s WHERE uid = %%s' % column, - (value, self._uid)) - if dbc.rowcount > 0: - self._dbh.commit() - dbc.close() - - def _count_aliases(self): - """Count all alias addresses where the destination address is the - address of the Account.""" - dbc = self._dbh.cursor() - dbc.execute('SELECT COUNT(destination) FROM alias WHERE destination ' - '= %s', (str(self._addr),)) - a_count = dbc.fetchone()[0] - dbc.close() - return a_count - - def _chk_state(self): - """Raise an AccountError if the Account is new - not yet saved in the - database.""" - if self._new: - raise AErr(_(u"The account '%s' does not exist.") % self._addr, - NO_SUCH_ACCOUNT) - - @property - def address(self): - """The Account's EmailAddress instance.""" - return self._addr - - @property - def domain(self): - """The Domain to which the Account belongs to.""" - if self._domain: - return self._domain - return None - - @property - def gid(self): - """The Account's group ID.""" - if self._domain: - return self._domain.gid - return None - - @property - def home(self): - """The Account's home directory.""" - if not self._new: - return '%s/%s' % (self._domain.directory, self._uid) - return None - - @property - def mail_location(self): - """The Account's MailLocation.""" - return self._mail - - @property - def note(self): - """The Account's note.""" - return self._note - - @property - def uid(self): - """The Account's unique ID.""" - return self._uid - - def set_password(self, password): - """Set a password for the new Account. - - If you want to update the password of an existing Account use - Account.modify(). - - Argument: - - `password` : basestring - The password for the new Account. - """ - if not self._new: - raise AErr(_(u"The account '%s' already exists.") % self._addr, - ACCOUNT_EXISTS) - if not isinstance(password, basestring) or not password: - raise AErr(_(u"Could not accept password: '%s'") % password, - ACCOUNT_MISSING_PASSWORD) - self._passwd = password - - def set_note(self, note): - """Set the account's (optional) note. - - Argument: - - `note` : basestring or None - The note, or None to remove - """ - assert note is None or isinstance(note, basestring) - self._note = note - - def save(self): - """Save the new Account in the database.""" - if not self._new: - raise AErr(_(u"The account '%s' already exists.") % self._addr, - ACCOUNT_EXISTS) - if not self._passwd: - raise AErr(_(u"No password set for account: '%s'") % self._addr, - ACCOUNT_MISSING_PASSWORD) - self._prepare(MailLocation(self._dbh, mbfmt=cfg_dget('mailbox.format'), - directory=cfg_dget('mailbox.root'))) - dbc = self._dbh.cursor() - qid = ssid = tid = None - if self._qlimit: - qid = self._qlimit.qid - if self._services: - ssid = self._services.ssid - if self._transport: - tid = self._transport.tid - dbc.execute('INSERT INTO users (local_part, passwd, uid, gid, mid, ' - 'qid, ssid, tid, note) ' - 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)', - (self._addr.localpart, - pwhash(self._passwd, user=self._addr), self._uid, - self._domain.gid, self._mail.mid, qid, ssid, tid, -# self._qlimit.qid if self._qlimit else None, -# self._services.ssid if self._services else None, -# self._transport.tid if self._transport else None, - self._note)) - self._dbh.commit() - dbc.close() - self._new = False - - def modify(self, field, value): - """Update the Account's *field* to the new *value*. - - Possible values for *field* are: 'name', 'password', 'note'. - - Arguments: - - `field` : basestring - The attribute name: 'name', 'password' or 'note' - `value` : basestring - The new value of the attribute. - """ - if field not in ('name', 'password', 'note'): - raise AErr(_(u"Unknown field: '%s'") % field, INVALID_ARGUMENT) - self._chk_state() - dbc = self._dbh.cursor() - if field == 'password': - dbc.execute('UPDATE users SET passwd = %s WHERE uid = %s', - (pwhash(value, user=self._addr), self._uid)) - else: - dbc.execute('UPDATE users SET %s = %%s WHERE uid = %%s' % field, - (value, self._uid)) - if dbc.rowcount > 0: - self._dbh.commit() - dbc.close() - - def update_quotalimit(self, quotalimit): - """Update the user's quota limit. - - Arguments: - - `quotalimit` : VirtualMailManager.quotalimit.QuotaLimit - the new quota limit of the domain. - """ - if cfg_dget('misc.dovecot_version') < 0x10102f00: - raise VMMError(_(u'PostgreSQL-based dictionary quota requires ' - u'Dovecot >= v1.1.2.'), VMM_ERROR) - self._chk_state() - if quotalimit == self._qlimit: - return - self._qlimit = quotalimit - if quotalimit is not None: - assert isinstance(quotalimit, QuotaLimit) - quotalimit = quotalimit.qid - self._update_tables('qid', quotalimit) - - def update_serviceset(self, serviceset): - """Assign a different set of services to the Account. - - Argument: - - `serviceset` : VirtualMailManager.serviceset.ServiceSet - the new service set. - """ - self._chk_state() - if serviceset == self._services: - return - self._services = serviceset - if serviceset is not None: - assert isinstance(serviceset, ServiceSet) - serviceset = serviceset.ssid - self._update_tables('ssid', serviceset) - - def update_transport(self, transport): - """Sets a new transport for the Account. - - Arguments: - - `transport` : VirtualMailManager.transport.Transport - the new transport - """ - self._chk_state() - if transport == self._transport: - return - self._transport = transport - if transport is not None: - assert isinstance(transport, Transport) - validate_transport(transport, self._mail) - transport = transport.tid - self._update_tables('tid', transport) - - def _get_info_transport(self): - if self._transport: - return self._transport.transport - return format_domain_default(self._domain.transport.transport) - - def _get_info_serviceset(self): - if self._services: - services = self._services.services - fmt = lambda s: s - else: - services = self._domain.serviceset.services - fmt = format_domain_default - - ret = {} - for service, state in services.iteritems(): - # TP: A service (e.g. pop3 or imap) may be enabled/usable or - # disabled/unusable for a user. - ret[service] = fmt((_('disabled'), _('enabled'))[state]) - return ret - - def get_info(self): - """Returns a dict with some information about the Account. - - The keys of the dict are: 'address', 'gid', 'home', 'imap' - 'mail_location', 'name', 'pop3', 'sieve', 'smtp', transport', 'uid', - 'uq_bytes', 'uq_messages', 'ql_bytes', 'ql_messages', and - 'ql_domaindefault'. - """ - self._chk_state() - dbc = self._dbh.cursor() - dbc.execute('SELECT name, CASE WHEN bytes IS NULL THEN 0 ELSE bytes ' - 'END, CASE WHEN messages IS NULL THEN 0 ELSE messages END ' - 'FROM users LEFT JOIN userquota USING (uid) WHERE ' - 'users.uid = %s', (self._uid,)) - info = dbc.fetchone() - dbc.close() - if info: - info = dict(zip(('name', 'uq_bytes', 'uq_messages'), info)) - info.update(self._get_info_serviceset()) - info['address'] = self._addr - info['gid'] = self._domain.gid - info['home'] = '%s/%s' % (self._domain.directory, self._uid) - info['mail_location'] = self._mail.mail_location - if self._qlimit: - info['ql_bytes'] = self._qlimit.bytes - info['ql_messages'] = self._qlimit.messages - info['ql_domaindefault'] = False - else: - info['ql_bytes'] = self._domain.quotalimit.bytes - info['ql_messages'] = self._domain.quotalimit.messages - info['ql_domaindefault'] = True - info['transport'] = self._get_info_transport() - info['note'] = self._note - info['uid'] = self._uid - return info - # nearly impossible‽ - raise AErr(_(u"Could not fetch information for account: '%s'") % - self._addr, NO_SUCH_ACCOUNT) - - def get_aliases(self): - """Return a list with all alias e-mail addresses, whose destination - is the address of the Account.""" - self._chk_state() - dbc = self._dbh.cursor() - dbc.execute("SELECT address ||'@'|| domainname FROM alias, " - "domain_name WHERE destination = %s AND domain_name.gid = " - "alias.gid AND domain_name.is_primary ORDER BY address", - (str(self._addr),)) - addresses = dbc.fetchall() - dbc.close() - aliases = [] - if addresses: - aliases = [alias[0] for alias in addresses] - return aliases - - def delete(self, force=False): - """Delete the Account from the database. - - Argument: - - `force` : bool - if *force* is `True`, all aliases, which points to the Account, - will be also deleted. If there are aliases and *force* is - `False`, an AccountError will be raised. - """ - if not isinstance(force, bool): - raise TypeError('force must be a bool') - self._chk_state() - dbc = self._dbh.cursor() - if force: - dbc.execute('DELETE FROM users WHERE uid = %s', (self._uid,)) - # delete also all aliases where the destination address is the same - # as for this account. - dbc.execute("DELETE FROM alias WHERE destination = %s", - (str(self._addr),)) - self._dbh.commit() - else: # check first for aliases - a_count = self._count_aliases() - if a_count > 0: - dbc.close() - raise AErr(_(u"There are %(count)d aliases with the " - u"destination address '%(address)s'.") % - {'count': a_count, 'address': self._addr}, - ALIAS_PRESENT) - dbc.execute('DELETE FROM users WHERE uid = %s', (self._uid,)) - self._dbh.commit() - dbc.close() - self._new = True - self._uid = 0 - self._addr = self._dbh = self._domain = self._passwd = None - self._mail = self._qlimit = self._services = self._transport = None - - -def get_account_by_uid(uid, dbh): - """Search an Account by its UID. - - This function returns a dict (keys: 'address', 'gid' and 'uid'), if an - Account with the given *uid* exists. - - Argument: - - `uid` : long - The Account unique ID. - `dbh` : pyPgSQL.PgSQL.Connection - a database connection for the database access. - """ - try: - uid = long(uid) - except ValueError: - raise AErr(_(u'UID must be an int/long.'), INVALID_ARGUMENT) - if uid < 1: - raise AErr(_(u'UID must be greater than 0.'), INVALID_ARGUMENT) - dbc = dbh.cursor() - dbc.execute("SELECT local_part||'@'|| domain_name.domainname AS address, " - "uid, users.gid, note FROM users LEFT JOIN domain_name ON " - "(domain_name.gid = users.gid AND is_primary) WHERE uid = %s", - (uid,)) - info = dbc.fetchone() - dbc.close() - if not info: - raise AErr(_(u"There is no account with the UID: '%d'") % uid, - NO_SUCH_ACCOUNT) - info = dict(zip(('address', 'uid', 'gid', 'note'), info)) - return info - -del _, cfg_dget diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/alias.py --- a/VirtualMailManager/alias.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.alias - ~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's Alias class to manage e-mail aliases. -""" - -from VirtualMailManager.domain import get_gid -from VirtualMailManager.emailaddress import \ - EmailAddress, DestinationEmailAddress as DestAddr -from VirtualMailManager.errors import AliasError as AErr -from VirtualMailManager.ext.postconf import Postconf -from VirtualMailManager.pycompat import all -from VirtualMailManager.constants import \ - ALIAS_EXCEEDS_EXPANSION_LIMIT, NO_SUCH_ALIAS, NO_SUCH_DOMAIN - - -_ = lambda msg: msg -cfg_dget = lambda option: None - - -class Alias(object): - """Class to manage e-mail aliases.""" - __slots__ = ('_addr', '_dests', '_gid', '_dbh') - - def __init__(self, dbh, address): - assert isinstance(address, EmailAddress) - self._addr = address - self._dbh = dbh - self._gid = get_gid(self._dbh, self._addr.domainname) - if not self._gid: - raise AErr(_(u"The domain '%s' does not exist.") % - self._addr.domainname, NO_SUCH_DOMAIN) - self._dests = [] - - self._load_dests() - - def _load_dests(self): - """Loads all known destination addresses into the _dests list.""" - dbc = self._dbh.cursor() - dbc.execute('SELECT destination FROM alias WHERE gid = %s AND ' - 'address = %s ORDER BY destination', - (self._gid, self._addr.localpart)) - dests = dbc.fetchall() - if dbc.rowcount > 0: - self._dests.extend(DestAddr(dest[0], self._dbh) for dest in dests) - dbc.close() - - def _check_expansion(self, count_new): - """Checks the current expansion limit of the alias.""" - postconf = Postconf(cfg_dget('bin.postconf')) - limit = long(postconf.read('virtual_alias_expansion_limit')) - dcount = len(self._dests) - failed = False - if dcount == limit or dcount + count_new > limit: - failed = True - errmsg = _( -u"""Cannot add %(count_new)i new destination(s) to alias '%(address)s'. -Currently this alias expands into %(count)i/%(limit)i recipients. -%(count_new)i additional destination(s) will render this alias unusable. -Hint: Increase Postfix' virtual_alias_expansion_limit""") - elif dcount > limit: - failed = True - errmsg = _( -u"""Cannot add %(count_new)i new destination(s) to alias '%(address)s'. -This alias already exceeds its expansion limit (%(count)i/%(limit)i). -So its unusable, all messages addressed to this alias will be bounced. -Hint: Delete some destination addresses.""") - if failed: - raise AErr(errmsg % {'address': self._addr, 'count': dcount, - 'limit': limit, 'count_new': count_new}, - ALIAS_EXCEEDS_EXPANSION_LIMIT) - - def _delete(self, destinations=None): - """Deletes the *destinations* from the alias, if ``destinations`` - is not ``None``. If ``destinations`` is None, the alias with all - its destination addresses will be deleted. - - """ - dbc = self._dbh.cursor() - if not destinations: - dbc.execute('DELETE FROM alias WHERE gid = %s AND address = %s', - (self._gid, self._addr.localpart)) - else: - dbc.executemany("DELETE FROM alias WHERE gid = %d AND address = " - "'%s' AND destination = %%s" % (self._gid, - self._addr.localpart), - ((str(dest),) for dest in destinations)) - if dbc.rowcount > 0: - self._dbh.commit() - dbc.close() - - def __len__(self): - """Returns the number of destinations of the alias.""" - return len(self._dests) - - @property - def address(self): - """The Alias' EmailAddress instance.""" - return self._addr - - def add_destinations(self, destinations, warnings=None): - """Adds the `EmailAddress`es from *destinations* list to the - destinations of the alias. - - Destinations, that are already assigned to the alias, will be - removed from *destinations*. When done, this method will return - a set with all destinations, that were saved in the database. - """ - destinations = set(destinations) - assert destinations and \ - all(isinstance(dest, EmailAddress) for dest in destinations) - if not warnings is None: - assert isinstance(warnings, list) - if self._addr in destinations: - destinations.remove(self._addr) - if not warnings is None: - warnings.append(self._addr) - duplicates = destinations.intersection(set(self._dests)) - if duplicates: - destinations.difference_update(set(self._dests)) - if not warnings is None: - warnings.extend(duplicates) - if not destinations: - return destinations - self._check_expansion(len(destinations)) - dbc = self._dbh.cursor() - dbc.executemany("INSERT INTO alias (gid, address, destination) " - "VALUES (%d, '%s', %%s)" % (self._gid, - self._addr.localpart), - ((str(destination),) for destination in destinations)) - self._dbh.commit() - dbc.close() - self._dests.extend(destinations) - return destinations - - def del_destinations(self, destinations, warnings=None): - """Delete the specified `EmailAddress`es of *destinations* from - the alias's destinations. - - """ - destinations = set(destinations) - assert destinations and \ - all(isinstance(dest, EmailAddress) for dest in destinations) - if not warnings is None: - assert isinstance(warnings, list) - if self._addr in destinations: - destinations.remove(self._addr) - if not warnings is None: - warnings.append(self._addr) - if not self._dests: - raise AErr(_(u"The alias '%s' does not exist.") % self._addr, - NO_SUCH_ALIAS) - unknown = destinations.difference(set(self._dests)) - if unknown: - destinations.intersection_update(set(self._dests)) - if not warnings is None: - warnings.extend(unknown) - if not destinations: - raise AErr(_(u"No suitable destinations left to remove from alias " - u"'%s'.") % self._addr, NO_SUCH_ALIAS) - self._delete(destinations) - for destination in destinations: - self._dests.remove(destination) - - def get_destinations(self): - """Returns an iterator for all destinations of the alias.""" - if not self._dests: - raise AErr(_(u"The alias '%s' does not exist.") % self._addr, - NO_SUCH_ALIAS) - return iter(self._dests) - - def delete(self): - """Deletes the alias with all its destinations.""" - if not self._dests: - raise AErr(_(u"The alias '%s' does not exist.") % self._addr, - NO_SUCH_ALIAS) - self._delete() - del self._dests[:] - -del _, cfg_dget diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/aliasdomain.py --- a/VirtualMailManager/aliasdomain.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2008 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.aliasdomain - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's AliasDomain class to manage alias domains. -""" - -from VirtualMailManager.domain import Domain, check_domainname -from VirtualMailManager.constants import \ - ALIASDOMAIN_EXISTS, ALIASDOMAIN_ISDOMAIN, ALIASDOMAIN_NO_DOMDEST, \ - NO_SUCH_ALIASDOMAIN, NO_SUCH_DOMAIN -from VirtualMailManager.errors import AliasDomainError as ADErr - - -_ = lambda msg: msg - - -class AliasDomain(object): - """Class to manage e-mail alias domains.""" - __slots__ = ('_gid', '_name', '_domain', '_dbh') - - def __init__(self, dbh, domainname): - """Creates a new AliasDomain instance. - - Arguments: - - `dbh` : pyPgSQL.PgSQL.Connection - a database connection for the database access - `domainname` : basestring - the name of the AliasDomain""" - self._dbh = dbh - self._name = check_domainname(domainname) - self._gid = 0 - self._domain = None - self._load() - - def _load(self): - """Loads the AliasDomain's GID from the database and checks if the - domain name is marked as primary.""" - dbc = self._dbh.cursor() - dbc.execute('SELECT gid, is_primary FROM domain_name WHERE ' - 'domainname = %s', (self._name,)) - result = dbc.fetchone() - dbc.close() - if result: - if result[1]: - raise ADErr(_(u"The domain '%s' is a primary domain.") % - self._name, ALIASDOMAIN_ISDOMAIN) - self._gid = result[0] - - def set_destination(self, dest_domain): - """Set the destination of a new AliasDomain or updates the - destination of an existing AliasDomain. - - Argument: - - `dest_domain` : VirtualMailManager.Domain.Domain - the AliasDomain's destination domain - """ - assert isinstance(dest_domain, Domain) - self._domain = dest_domain - - def save(self): - """Stores information about the new AliasDomain in the database.""" - if self._gid > 0: - raise ADErr(_(u"The alias domain '%s' already exists.") % - self._name, ALIASDOMAIN_EXISTS) - if not self._domain: - raise ADErr(_(u'No destination domain set for the alias domain.'), - ALIASDOMAIN_NO_DOMDEST) - if self._domain.gid < 1: - raise ADErr(_(u"The target domain '%s' does not exist.") % - self._domain.name, NO_SUCH_DOMAIN) - dbc = self._dbh.cursor() - dbc.execute('INSERT INTO domain_name (domainname, gid, is_primary) ' - 'VALUES (%s, %s, FALSE)', (self._name, self._domain.gid)) - self._dbh.commit() - dbc.close() - self._gid = self._domain.gid - - def info(self): - """Returns a dict (keys: "alias" and "domain") with the names of the - AliasDomain and its primary domain.""" - if self._gid < 1: - raise ADErr(_(u"The alias domain '%s' does not exist.") % - self._name, NO_SUCH_ALIASDOMAIN) - dbc = self._dbh.cursor() - dbc.execute('SELECT domainname FROM domain_name WHERE gid = %s AND ' - 'is_primary', (self._gid,)) - domain = dbc.fetchone() - dbc.close() - if domain: - return {'alias': self._name, 'domain': domain[0]} - else: # an almost unlikely case, isn't it? - raise ADErr(_(u'There is no primary domain for the alias domain ' - u"'%s'.") % self._name, NO_SUCH_DOMAIN) - - def switch(self): - """Switch the destination of the AliasDomain to the new destination, - set with the method `set_destination()`. - """ - if not self._domain: - raise ADErr(_(u'No destination domain set for the alias domain.'), - ALIASDOMAIN_NO_DOMDEST) - if self._domain.gid < 1: - raise ADErr(_(u"The target domain '%s' does not exist.") % - self._domain.name, NO_SUCH_DOMAIN) - if self._gid < 1: - raise ADErr(_(u"The alias domain '%s' does not exist.") % - self._name, NO_SUCH_ALIASDOMAIN) - if self._gid == self._domain.gid: - raise ADErr(_(u"The alias domain '%(alias)s' is already assigned " - u"to the domain '%(domain)s'.") % - {'alias': self._name, 'domain': self._domain.name}, - ALIASDOMAIN_EXISTS) - dbc = self._dbh.cursor() - dbc.execute('UPDATE domain_name SET gid = %s WHERE gid = %s AND ' - 'domainname = %s AND NOT is_primary', (self._domain.gid, - self._gid, self._name)) - self._dbh.commit() - dbc.close() - self._gid = self._domain.gid - - def delete(self): - """Delete the AliasDomain's record form the database. - - Raises an AliasDomainError if the AliasDomain doesn't exist. - """ - if self._gid < 1: - raise ADErr(_(u"The alias domain '%s' does not exist.") % - self._name, NO_SUCH_ALIASDOMAIN) - dbc = self._dbh.cursor() - dbc.execute('DELETE FROM domain_name WHERE domainname = %s AND NOT ' - 'is_primary', (self._name,)) - if dbc.rowcount > 0: - self._dbh.commit() - self._gid = 0 - dbc.close() - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/catchall.py --- a/VirtualMailManager/catchall.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,181 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2012 - 2014, martin f. krafft -# See COPYING for distribution information. -""" - VirtualMailManager.catchall - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's CatchallAlias class to manage domain catch-all - aliases. - - This is heavily based on (more or less a copy of) the Alias class, because - fundamentally, catchall aliases are aliases, but without a localpart. - While Alias could potentially derive from CatchallAlias to reuse some of - the functionality, it's probably not worth it. I found no sensible way to - derive CatchallAlias from Alias, or at least none that would harness the - powers of polymorphism. - - Yet, we reuse the AliasError exception class, which makes sense. -""" - -from VirtualMailManager.domain import get_gid -from VirtualMailManager.emailaddress import \ - EmailAddress, DestinationEmailAddress as DestAddr -from VirtualMailManager.errors import AliasError as AErr -from VirtualMailManager.ext.postconf import Postconf -from VirtualMailManager.pycompat import all -from VirtualMailManager.constants import \ - ALIAS_EXCEEDS_EXPANSION_LIMIT, NO_SUCH_ALIAS, NO_SUCH_DOMAIN - - -_ = lambda msg: msg -cfg_dget = lambda option: None - - -class CatchallAlias(object): - """Class to manage domain catch-all aliases.""" - __slots__ = ('_domain', '_dests', '_gid', '_dbh') - - def __init__(self, dbh, domain): - self._domain = domain - self._dbh = dbh - self._gid = get_gid(self._dbh, self.domain) - if not self._gid: - raise AErr(_(u"The domain '%s' does not exist.") % - self.domain, NO_SUCH_DOMAIN) - self._dests = [] - - self._load_dests() - - def _load_dests(self): - """Loads all known destination addresses into the _dests list.""" - dbc = self._dbh.cursor() - dbc.execute('SELECT destination FROM catchall WHERE gid = %s', - (self._gid,)) - dests = dbc.fetchall() - if dbc.rowcount > 0: - self._dests.extend(DestAddr(dest[0], self._dbh) for dest in dests) - dbc.close() - - def _check_expansion(self, count_new): - """Checks the current expansion limit of the alias.""" - postconf = Postconf(cfg_dget('bin.postconf')) - limit = long(postconf.read('virtual_alias_expansion_limit')) - dcount = len(self._dests) - failed = False - if dcount == limit or dcount + count_new > limit: - failed = True - errmsg = _( -u"""Cannot add %(count_new)i new destination(s) to catch-all alias for -domain '%(domain)s'. Currently this alias expands into %(count)i/%(limit)i -recipients. %(count_new)i additional destination(s) will render this alias -unusable. -Hint: Increase Postfix' virtual_alias_expansion_limit""") - elif dcount > limit: - failed = True - errmsg = _( -u"""Cannot add %(count_new)i new destination(s) to catch-all alias for domain -'%(domain)s'. This alias already exceeds its expansion limit \ -(%(count)i/%(limit)i). -So its unusable, all messages addressed to this alias will be bounced. -Hint: Delete some destination addresses.""") - if failed: - raise AErr(errmsg % {'domain': self._domain, 'count': dcount, - 'limit': limit, 'count_new': count_new}, - ALIAS_EXCEEDS_EXPANSION_LIMIT) - - def _delete(self, destinations=None): - """Delete one ore multiple destinations from the catchall alias, if - ``destinations`` is not ``None``. If ``destinations`` is None, the - catchall alias with all its destination addresses will be deleted. - - """ - dbc = self._dbh.cursor() - if not destinations: - dbc.execute('DELETE FROM catchall WHERE gid = %s', (self._gid,)) - else: - dbc.executemany('DELETE FROM catchall WHERE gid = %d AND ' - 'destination = %%s' % self._gid, - ((str(dest),) for dest in destinations)) - if dbc.rowcount > 0: - self._dbh.commit() - dbc.close() - - def __len__(self): - """Returns the number of destinations of the catchall alias.""" - return len(self._dests) - - @property - def domain(self): - """The Alias' domain.""" - return self._domain - - def add_destinations(self, destinations, warnings=None): - """Adds the `EmailAddress`es from *destinations* list to the - destinations of the catchall alias. - - Destinations, that are already assigned to the alias, will be - removed from *destinations*. When done, this method will return - a set with all destinations, that were saved in the database. - """ - destinations = set(destinations) - assert destinations and \ - all(isinstance(dest, EmailAddress) for dest in destinations) - if not warnings is None: - assert isinstance(warnings, list) - duplicates = destinations.intersection(set(self._dests)) - if duplicates: - destinations.difference_update(set(self._dests)) - if not warnings is None: - warnings.extend(duplicates) - if not destinations: - return destinations - self._check_expansion(len(destinations)) - dbc = self._dbh.cursor() - dbc.executemany("INSERT INTO catchall (gid, destination) " - "VALUES (%d, %%s)" % self._gid, - ((str(destination),) for destination in destinations)) - self._dbh.commit() - dbc.close() - self._dests.extend(destinations) - return destinations - - def del_destinations(self, destinations, warnings=None): - """Deletes the specified ``destinations`` from the catchall alias.""" - destinations = set(destinations) - assert destinations and \ - all(isinstance(dest, EmailAddress) for dest in destinations) - if not warnings is None: - assert isinstance(warnings, list) - if not self._dests: - raise AErr(_(u"There are no catch-all aliases defined for " - u"domain '%s'.") % self._domain, NO_SUCH_ALIAS) - unknown = destinations.difference(set(self._dests)) - if unknown: - destinations.intersection_update(set(self._dests)) - if not warnings is None: - warnings.extend(unknown) - if not destinations: - raise AErr(_(u"No suitable destinations left to remove from the " - u"catch-all alias of domain '%s'.") % self._domain, - NO_SUCH_ALIAS) - self._delete(destinations) - for destination in destinations: - self._dests.remove(destination) - - def get_destinations(self): - """Returns an iterator for all destinations of the catchall alias.""" - if not self._dests: - raise AErr(_(u"There are no catch-all aliases defined for " - u"domain '%s'.") % self._domain, NO_SUCH_ALIAS) - return iter(self._dests) - - def delete(self): - """Deletes all catchall destinations for the domain.""" - if not self._dests: - raise AErr(_(u"There are no catch-all aliases defined for " - u"domain '%s'.") % self._domain, NO_SUCH_ALIAS) - self._delete() - del self._dests[:] - -del _, cfg_dget diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/cli/__init__.py --- a/VirtualMailManager/cli/__init__.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2010 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.cli - ~~~~~~~~~~~~~~~~~~~~~~ - - VirtualMailManager's command line interface. -""" - -import os -from array import array -from fcntl import ioctl -from getpass import getpass -from termios import TIOCGWINSZ - -from VirtualMailManager import ENCODING -from VirtualMailManager.constants import VMM_TOO_MANY_FAILURES -from VirtualMailManager.errors import VMMError - - -__all__ = ('prog', 'get_winsize', 'read_pass', 'w_err', 'w_std') - -_ = lambda msg: msg -_std_write = os.sys.stdout.write -_err_write = os.sys.stderr.write -prog = os.path.basename(os.sys.argv[0]) - - -def w_std(*args): - """Writes a line for each arg of *args*, encoded in the current - ENCODING, to stdout. - """ - _std_write('\n'.join(a.encode(ENCODING, 'replace') for a in args) + '\n') - - -def w_err(code, *args): - """Writes a line for each arg of *args*, encoded in the current - ENCODING, to stderr. - This function optionally interrupts the program execution if *code* - does not equal to 0. *code* will be used as the system exit status. - """ - _err_write('\n'.join(a.encode(ENCODING, 'replace') for a in args) + '\n') - if code: - os.sys.exit(code) - - -def get_winsize(): - """Returns a tuple of integers ``(ws_row, ws_col)`` with the height and - width of the terminal.""" - fd = None - for dev in (os.sys.stdout, os.sys.stderr, os.sys.stdin): - if hasattr(dev, 'fileno') and os.isatty(dev.fileno()): - fd = dev.fileno() - break - if fd is None: # everything seems to be redirected - # fall back to environment or assume some common defaults - ws_row, ws_col = 24, 80 - try: - ws_col = int(os.environ.get('COLUMNS', 80)) - ws_row = int(os.environ.get('LINES', 24)) - except ValueError: - pass - return ws_row, ws_col - #"struct winsize" with the ``unsigned short int``s ws_{row,col,{x,y}pixel} - ws = array('H', (0, 0, 0, 0)) - ioctl(fd, TIOCGWINSZ, ws, True) - ws_row, ws_col = ws[:2] - return ws_row, ws_col - - -def read_pass(): - """Interactive 'password chat', returns the password in plain format. - - Throws a VMMError after the third failure. - """ - # TP: Please preserve the trailing space. - readp_msg0 = _(u'Enter new password: ').encode(ENCODING, 'replace') - # TP: Please preserve the trailing space. - readp_msg1 = _(u'Retype new password: ').encode(ENCODING, 'replace') - mismatched = True - failures = 0 - while mismatched: - if failures > 2: - raise VMMError(_(u'Too many failures - try again later.'), - VMM_TOO_MANY_FAILURES) - clear0 = getpass(prompt=readp_msg0) - clear1 = getpass(prompt=readp_msg1) - if clear0 != clear1: - failures += 1 - w_err(0, _(u'Sorry, passwords do not match.')) - continue - if not clear0: - failures += 1 - w_err(0, _(u'Sorry, empty passwords are not permitted.')) - continue - mismatched = False - return clear0 - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/cli/clihelp.py --- a/VirtualMailManager/cli/clihelp.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,262 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2012 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.cli.vmmhelp - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's command line help. -""" - -_ = lambda msg: msg - -help_msgs = { -# TP: There are some words enclosed within angle brackets '<'word'>'. They -# are used to indicate replaceable arguments. Please do not translate them. -# -# The descriptions of subcommands may contain the both keywords 'domain' -# and 'force', enclosed within single quotes. Please keep them as they are. -# - # TP: description of subcommand configget - 'configget': (_(u"""This subcommand is used to display the actual value -of the given configuration <option>."""),), - # TP: description of subcommand configset - 'configset': (_(u"""Use this subcommand to set or update a single -configuration option's value. <option> is the configuration option, <value> -is the <option>'s new value."""), -_(u"""Note: This subcommand will create a new vmm.cfg without any comments. -Your current configuration file will be backed as vmm.cfg.bak."""),), - # TP: description of subcommand configure - 'configure': (_(u"""Starts the interactive configuration for all -configuration sections."""), -_(u"""In this process the currently set value of each option will be displayed -in square brackets. If no value is configured, the default value of each -option will be displayed in square brackets. Press the return key, to accept -the displayed value."""), -_(u"""If the optional argument <section> is given, only the configuration -options from the given section will be displayed and will be configurable. -The following sections are available: -"""), -""" account, bin, database, domain, mailbox, misc""", -_(u"""All configuration options are described in vmm.cfg(5)."""), -_(u"""Note: This subcommand will create a new vmm.cfg without any comments. -Your current configuration file will be backed as vmm.cfg.bak."""),), - # TP: description of subcommand getuser - 'getuser': (_(u"""If only the <uid> is available, for example from process -list, the subcommand getuser will show the user's address."""),), - # TP: description of subcommand listaddresses - 'listaddresses': (_(u"""This command lists all defined addresses. -Addresses belonging to alias-domains are prefixed with a '-', addresses of -regular domains with a '+'. Additionally, the letters 'u', 'a', and 'r' -indicate the type of each address: user, alias and relocated respectively. -The output can be limited with an optional <pattern>."""), -_(u"""To perform a wild card search, the % character can be used at the start -and/or the end of the <pattern>."""),), - # TP: description of subcommand listaliases - 'listaliases': (_(u"""This command lists all defined aliases. Aliases -belonging to alias-domains are prefixed with a '-', addresses of regular -domains with a '+'. The output can be limited with an optional <pattern>."""), -# xgettext:no-python-format -_(u"""To perform a wild card search, the % character can be used at the start -and/or the end of the <pattern>."""),), - # TP: description of subcommand listdomains - 'listdomains': (_(u"""This subcommand lists all available domains. All -domain names will be prefixed either with `[+]', if the domain is a primary -domain, or with `[-]', if it is an alias domain name. The output can be -limited with an optional <pattern>."""), -_(u"""To perform a wild card search, the % character can be used at the start -and/or the end of the <pattern>."""),), - # TP: description of subcommand listpwschemes - 'listpwschemes': (_(u"""This subcommand lists all password schemes which -could be used in the vmm.cfg as value of the misc.password_scheme option. -The output varies, depending on the used Dovecot version and the system's -libc."""), -_(u"""When your Dovecot installation isn't too old, you will see additionally -a few usable encoding suffixes. One of them can be appended to the password -scheme."""),), - # TP: description of subcommand listrelocated - 'listrelocated': (_(u"""This command lists all defined relocated addresses. -Relocated entries belonging to alias-domains are prefixed with a '-', addresses -of regular domains with a '+'. The output can be limited with an optional -<pattern>."""), -_(u"""To perform a wild card search, the % character can be used at the start -and/or the end of the <pattern>."""),), - # TP: description of subcommand listusers - 'listusers': (_(u"""This command lists all user accounts. User accounts -belonging to alias-domains are prefixed with a '-', addresses of regular -domains with a '+'. The output can be limited with an optional <pattern>."""), -_(u"""To perform a wild card search, the % character can be used at the start -and/or the end of the <pattern>."""),), - # TP: description of subcommand version - 'version': (_(u"""Prints vmm's version and copyright information to stdout. -After this vmm exits."""),), - # TP: description of subcommand domainadd - 'domainadd': (_(u"""Adds the new domain into the database and creates the -domain directory."""), -_(u"""If the optional argument <transport> is given, it will override the -default transport (domain.transport) from vmm.cfg. The specified <transport> -will be the default transport for all new accounts in this domain."""), -_(u"""Configuration-related behavior:"""), -u""" * domain.auto_postmaster""", -_(u"""When that option is set to true (default) vmm will automatically create -the postmaster account for the new domain and prompt for postmaster@<fqdn>'s -password."""), -u""" * account.random_password""", -_(u"""When the value of that option is also set to true, vmm will automatically -create the postmaster account for the new domain and print the generated -postmaster password to stdout."""),), - # TP: description of subcommand domaindelete - 'domaindelete': (_(u"""This subcommand deletes the domain specified by -<fqdn>."""), -_(u"""If there are accounts, aliases and/or relocated users assigned to the -given domain, vmm will abort the requested operation and show an error -message. If you know, what you are doing, you can specify the optional keyword -'force'."""), -_(u"""If you really always know what you are doing, edit your vmm.cfg and set -the option domain.force_deletion to true."""),), - # TP: description of subcommand domaininfo - 'domaininfo': (_(u"""This subcommand shows some information about the -given domain."""), -_(u"""For a more detailed information about the domain the optional argument -<details> can be specified. A possible <details> value can be one of the -following six keywords:"""), -""" accounts, aliasdomains, aliases, catchall, relocated, full""",), - # TP: description of subcommand domainquota - 'domainquota': (_(u"""This subcommand is used to configure a new quota -limit for the accounts of the domain - not for the domain itself."""), -_(u"""The default quota limit for accounts is defined in the vmm.cfg -(domain.quota_bytes and domain.quota_messages)."""), -_(u"""The new quota limit will affect only those accounts for which the limit -has not been overridden. If you want to restore the default to all accounts, -you may pass the keyword 'force'. When the argument <messages> was omitted the -default number of messages 0 (zero) will be applied."""),), - # TP: description of subcommand domainservices - 'domainservices': (_(u"""To define which services could be used by the -users of the domain — with the given <fqdn> — use this subcommand."""), -_(u"""Each specified <service> will be enabled/usable. All other services -will be deactivated/unusable. Possible <service> names are:"""), -u""" imap, pop3, sieve, smtp""", -_(u"""The new service set will affect only those accounts for which the set has -not been overridden. If you want to restore the default to all accounts, you -may pass the keyword 'force'."""),), - # TP: description of subcommand domaintransport - 'domaintransport': (_(u"""A new transport for the indicated domain can be -set with this subcommand."""), -_(u"""The new transport will affect only those accounts for which the transport -has not been overridden. If you want to restore the default to all accounts, -you may pass the keyword 'force'."""),), - # TP: description of subcommand domainnote - 'domainnote': (_(u"""With this subcommand, it is possible to attach a -note to the specified domain. Without an argument, an existing note is -removed."""),), - # TP: description of subcommand aliasdomainadd - 'aliasdomainadd': (_(u"""This subcommand adds the new alias domain -(<fqdn>) to the destination <domain> that should be aliased."""),), - # TP: description of subcommand aliasdomaindelete - 'aliasdomaindelete': (_(u"""Use this subcommand if the alias domain -<fqdn> should be removed."""),), - # TP: description of subcommand aliasdomaininfo - 'aliasdomaininfo': (_(u"""This subcommand shows to which domain the alias -domain <fqdn> is assigned to."""),), - # TP: description of subcommand aliasdomainswitch - 'aliasdomainswitch': (_(u"""If the destination of the existing alias -domain <fqdn> should be switched to another <destination> use this -subcommand."""),), - # TP: description of subcommand useradd - 'useradd': (_(u"""Use this subcommand to create a new e-mail account for -the given <address>."""), -_(u"""If the <password> is not provided, vmm will prompt for it interactively. -When no <password> is provided and account.random_password is set to true, vmm -will generate a random password and print it to stdout after the account has -been created."""),), - # TP: description of subcommand userdelete - 'userdelete': (_(u"""Use this subcommand to delete the account with the -given <address>."""), -_(u"""If there are one or more aliases with an identical destination address, -vmm will abort the requested operation and show an error message. To prevent -this, specify the optional keyword 'force'."""),), - # TP: description of subcommand userinfo - 'userinfo': (_(u"""This subcommand displays some information about the -account specified by <address>."""), -_(u"""If the optional argument <details> is given some more information will be -displayed. Possible values for <details> are:"""), -u""" aliases, du. full""",), - # TP: description of subcommand username - 'username': (_(u"""The user's real <name> can be set/updated with this -subcommand."""), -_(u"""If no <name> is given, the value stored for the account is erased."""), -), - # TP: description of subcommand userpassword - 'userpassword': (_(u"""The password of an account can be updated with this -subcommand."""), -_(u"""If no <password> was provided, vmm will prompt for it interactively."""), -), - # TP: description of subcommand usernote - 'usernote': (_(u"""With this subcommand, it is possible to attach a note -to the specified account. Without an argument, an existing note is -removed."""),), - # TP: description of subcommand userquota - 'userquota': (_(u"""This subcommand is used to set a new quota limit for -the given account."""), -_(u"""When the argument <messages> was omitted the default number of messages -0 (zero) will be applied."""), -_(u"""Instead of <storage> pass the keyword 'domain' to remove the -account-specific override, causing the domain's value to be in effect."""),), - # TP: description of subcommand userservices - 'userservices': (_(u"""To grant a user access to the specified services, -use this command."""), -_(u"""All omitted services will be deactivated/unusable for the user with the -given <address>."""), -_(u"""Instead of <service> pass 'domain' to remove the account-specific -override, causing the domain's value to be in effect."""),), - # TP: description of subcommand usertransport - 'usertransport': (_(u"""A different <transport> for an account can be -specified with this subcommand."""), -_(u"""Instead of <transport> pass 'domain' to remove the account-specific -override, causing the domain's value to be in effect."""),), - # TP: description of subcommand aliasadd - 'aliasadd': (_(u"""This subcommand is used to create a new alias -<address> with one or more <destination> addresses."""), -_(u"""Within the destination address, the placeholders '%n', '%d', and '%=' -will be replaced by the local part, the domain, or the email address with '@' -replaced by '=' respectively. In combination with alias domains, this enables -domain-specific destinations."""),), - # TP: description of subcommand aliasdelete - 'aliasdelete': (_(u"""This subcommand is used to delete one or multiple -<destination>s from the alias with the given <address>."""), -_(u"""When no <destination> address was specified the alias with all its -destinations will be deleted."""),), - # TP: description of subcommand aliasinfo - 'aliasinfo': (_(u"""Information about the alias with the given <address> -can be displayed with this subcommand."""),), - # TP: description of subcommand relocatedadd - 'relocatedadd': (_(u"""A new relocated user can be created with this -subcommand."""), -_(u"""<address> is the user's ex-email address, for example -b.user@example.com, and <newaddress> points to the new email address where -the user can be reached."""),), - # TP: description of subcommand relocatedinfo - 'relocatedinfo': (_(u"""This subcommand shows the new address of the -relocated user with the given <address>."""),), - # TP: description of subcommand relocateddelete - 'relocateddelete': (_(u"""Use this subcommand in order to delete the -relocated user with the given <address>."""),), - # TP: description of subcommand catchalladd - 'catchalladd': (_(u"""This subcommand allows to specify destination -addresses for a domain, which shall receive mail addressed to unknown -local-parts within that domain. Those catch-all aliases hence "catch all" mail -to any address in the domain (unless a more specific alias, mailbox or -relocated user exists)."""), -_(u"""WARNING: Catch-all addresses can cause mail server flooding because -spammers like to deliver mail to all possible combinations of names, e.g. -to all addresses between abba@example.org and zztop@example.org."""),), - # TP: description of subcommand catchallinfo - 'catchallinfo': (_(u"""This subcommand displays information about catch-all -aliases defined for the domain <fqdn>."""),), - # TP: description of subcommand catchalldelete - 'catchalldelete': (_(u"""With this subcommand, catch-all aliases defined -for a domain can be removed, either all of them, or those <destination>s which -were specified explicitly."""),), -} - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/cli/config.py --- a/VirtualMailManager/cli/config.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2010 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.cli.config - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Adds some interactive stuff to the Config class. -""" - -from ConfigParser import RawConfigParser -from shutil import copy2 - -from VirtualMailManager import ENCODING -from VirtualMailManager.config import Config, ConfigValueError, LazyConfig -from VirtualMailManager.errors import ConfigError, VMMError -from VirtualMailManager.cli import w_err, w_std -from VirtualMailManager.constants import CONF_ERROR, VMM_TOO_MANY_FAILURES - -_ = lambda msg: msg - - -class CliConfig(Config): - """Adds the interactive ``configure`` method to the `Config` class - and overwrites `LazyConfig.set(), in order to update a single option - in the configuration file with a single command line command. - """ - - def configure(self, sections): - """Interactive method for configuring all options of the given - iterable ``sections`` object.""" - input_fmt = _(u'Enter new value for option %(option)s ' - u'[%(current_value)s]: ') - failures = 0 - - w_std(_(u'Using configuration file: %s\n') % self._cfg_filename) - for section in sections: - w_std(_(u"* Configuration section: '%s'") % section) - for opt, val in self.items(section): - failures = 0 - while True: - newval = raw_input(input_fmt.encode(ENCODING, 'replace') % - {'option': opt, 'current_value': val}) - if newval and newval != val: - try: - LazyConfig.set(self, '%s.%s' % (section, opt), - newval) - break - except (ValueError, ConfigValueError, VMMError), err: - w_err(0, _(u'Warning: %s') % err) - failures += 1 - if failures > 2: - raise ConfigError(_(u'Too many failures - try ' - u'again later.'), - VMM_TOO_MANY_FAILURES) - else: - break - print - if self._modified: - self._save_changes() - - def set(self, option, value): - """Set the value of an option. - - If the new `value` has been set, the configuration file will be - immediately updated. - - Throws a ``ConfigError`` if `value` couldn't be converted to - ``LazyConfigOption.cls`` or ``LazyConfigOption.validate`` fails.""" - section, option_ = self._get_section_option(option) - try: - val = self._cfg[section][option_].cls(value) - if self._cfg[section][option_].validate: - val = self._cfg[section][option_].validate(val) - except (ValueError, ConfigValueError), err: - raise ConfigError(str(err), CONF_ERROR) - # Do not write default values also skip identical values - if not self._cfg[section][option_].default is None: - old_val = self.dget(option) - else: - old_val = self.pget(option) - if val == old_val: - return - if not RawConfigParser.has_section(self, section): - self.add_section(section) - RawConfigParser.set(self, section, option_, val) - self._save_changes() - - def _save_changes(self): - """Writes changes to the configuration file.""" - copy2(self._cfg_filename, self._cfg_filename + '.bak') - self._cfg_file = open(self._cfg_filename, 'w') - self.write(self._cfg_file) - self._cfg_file.close() - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/cli/handler.py --- a/VirtualMailManager/cli/handler.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2010 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.cli.handler - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - A derived Handler class with a few changes/additions for cli use. -""" - -import os - -from VirtualMailManager.errors import VMMError -from VirtualMailManager.handler import Handler -from VirtualMailManager.cli import read_pass -from VirtualMailManager.cli.config import CliConfig as Cfg -from VirtualMailManager.constants import ACCOUNT_EXISTS, INVALID_SECTION, \ - NO_SUCH_ACCOUNT, TYPE_ACCOUNT -from VirtualMailManager.password import randompw - -_ = lambda msg: msg - - -class CliHandler(Handler): - """This class uses a `CliConfig` for configuration stuff, instead of - the non-interactive `Config` class. - - It provides the additional methods cfgSet() and configure(). - - Additionally it uses `VirtualMailManager.cli.read_pass()` for for the - interactive password dialog. - """ - - __slots__ = () # nothing additional, also no __dict__/__weakref__ - - def __init__(self): - """Creates a new CliHandler instance. - - Throws a NotRootError if your uid is greater 0. - """ - # Overwrite the parent CTor partly, we use the CliConfig class - # and add some command line checks. - skip_some_checks = os.sys.argv[1] in ('cf', 'configure', 'h', 'help', - 'v', 'version') - super(CliHandler, self).__init__(skip_some_checks) - - self._cfg = Cfg(self._cfg_fname) - self._cfg.load() - - def cfg_set(self, option, value): - """Set a new value for the given option.""" - return self._cfg.set(option, value) - - def configure(self, section=None): - """Starts the interactive configuration. - - Configures in interactive mode options in the given ``section``. - If no section is given (default) all options from all sections - will be prompted. - """ - if section is None: - self._cfg.configure(self._cfg.sections()) - elif self._cfg.has_section(section): - self._cfg.configure([section]) - else: - raise VMMError(_(u"Invalid section: '%s'") % section, - INVALID_SECTION) - - def user_add(self, emailaddress, password=None): - """Override the parent user_add() - add the interactive password - dialog. - - Returns the generated password, if account.random_password == True. - """ - acc = self._get_account(emailaddress) - if acc: - raise VMMError(_(u"The account '%s' already exists.") % - acc.address, ACCOUNT_EXISTS) - self._is_other_address(acc.address, TYPE_ACCOUNT) - rand_pass = self._cfg.dget('account.random_password') - if password is None: - password = (read_pass, randompw)[rand_pass]() - acc.set_password(password) - acc.save() - self._make_account_dirs(acc) - return (None, password)[rand_pass] - - def user_password(self, emailaddress, password=None): - """Override the parent user_password() - add the interactive - password dialog.""" - acc = self._get_account(emailaddress) - if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % - acc.address, NO_SUCH_ACCOUNT) - if not isinstance(password, basestring) or not password: - password = read_pass() - acc.modify('password', password) - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/cli/main.py --- a/VirtualMailManager/cli/main.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.cli.main - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - VirtualMailManager's command line interface. -""" - -from ConfigParser import NoOptionError, NoSectionError - -from VirtualMailManager import ENCODING, errors -from VirtualMailManager.config import BadOptionError, ConfigValueError -from VirtualMailManager.cli import w_err -from VirtualMailManager.cli.handler import CliHandler -from VirtualMailManager.constants import DATABASE_ERROR, EX_MISSING_ARGS, \ - EX_SUCCESS, EX_UNKNOWN_COMMAND, EX_USER_INTERRUPT, INVALID_ARGUMENT -from VirtualMailManager.cli.subcommands import RunContext, cmd_map, \ - update_cmd_map, usage - - -_ = lambda msg: msg - - -def _get_handler(): - """Try to get a CliHandler. Exit the program when an error occurs.""" - try: - handler = CliHandler() - except (errors.NotRootError, errors.PermissionError, errors.VMMError, - errors.ConfigError), err: - w_err(err.code, _(u'Error: %s') % err.msg) - else: - handler.cfg_install() - return handler - - -def run(argv): - update_cmd_map() - if len(argv) < 2: - usage(EX_MISSING_ARGS, _(u"You must specify a subcommand at least.")) - - sub_cmd = argv[1].lower() - if sub_cmd in cmd_map: - cmd_func = cmd_map[sub_cmd].func - else: - for cmd in cmd_map.itervalues(): - if cmd.alias == sub_cmd: - cmd_func = cmd.func - sub_cmd = cmd.name - break - else: - usage(EX_UNKNOWN_COMMAND, _(u"Unknown subcommand: '%s'") % sub_cmd) - - handler = _get_handler() - run_ctx = RunContext(argv, handler, sub_cmd) - try: - cmd_func(run_ctx) - except (EOFError, KeyboardInterrupt): - # TP: We have to cry, because root has killed/interrupted vmm - # with Ctrl+C or Ctrl+D. - w_err(EX_USER_INTERRUPT, '', _(u'Ouch!'), '') - except errors.VMMError, err: - if err.code != DATABASE_ERROR: - if handler.has_warnings(): - w_err(0, _(u'Warnings:'), *handler.get_warnings()) - w_err(err.code, _(u'Error: %s') % err.msg) - w_err(err.code, unicode(err.msg, ENCODING, 'replace')) - except (BadOptionError, ConfigValueError), err: - w_err(INVALID_ARGUMENT, _(u'Error: %s') % err) - except NoSectionError, err: - w_err(INVALID_ARGUMENT, - _(u"Error: Unknown section: '%s'") % err.section) - except NoOptionError, err: - w_err(INVALID_ARGUMENT, - _(u"Error: No option '%(option)s' in section: '%(section)s'") % - {'option': err.option, 'section': err.section}) - if handler.has_warnings(): - w_err(0, _(u'Warnings:'), *handler.get_warnings()) - return EX_SUCCESS - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/cli/subcommands.py --- a/VirtualMailManager/cli/subcommands.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1127 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.cli.subcommands - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - VirtualMailManager's cli subcommands. -""" - -import locale -import os - -from textwrap import TextWrapper -from time import strftime, strptime - -from VirtualMailManager import ENCODING -from VirtualMailManager.cli import get_winsize, prog, w_err, w_std -from VirtualMailManager.cli.clihelp import help_msgs -from VirtualMailManager.common import human_size, size_in_bytes, \ - version_str, format_domain_default -from VirtualMailManager.constants import __copyright__, __date__, \ - __version__, ACCOUNT_EXISTS, ALIAS_EXISTS, ALIASDOMAIN_ISDOMAIN, \ - DOMAIN_ALIAS_EXISTS, INVALID_ARGUMENT, EX_MISSING_ARGS, \ - RELOCATED_EXISTS, TYPE_ACCOUNT, TYPE_ALIAS, TYPE_RELOCATED -from VirtualMailManager.errors import VMMError -from VirtualMailManager.password import list_schemes -from VirtualMailManager.serviceset import SERVICES - -__all__ = ( - 'Command', 'RunContext', 'cmd_map', 'usage', 'alias_add', 'alias_delete', - 'alias_info', 'aliasdomain_add', 'aliasdomain_delete', 'aliasdomain_info', - 'aliasdomain_switch', 'catchall_add', 'catchall_info', 'catchall_delete', - 'config_get', 'config_set', 'configure', - 'domain_add', 'domain_delete', 'domain_info', 'domain_quota', - 'domain_services', 'domain_transport', 'domain_note', 'get_user', 'help_', - 'list_domains', 'list_pwschemes', 'list_users', 'list_aliases', - 'list_relocated', 'list_addresses', 'relocated_add', 'relocated_delete', - 'relocated_info', 'user_add', 'user_delete', 'user_info', 'user_name', - 'user_password', 'user_quota', 'user_services', 'user_transport', - 'user_note', 'version', -) - -_ = lambda msg: msg -txt_wrpr = TextWrapper(width=get_winsize()[1] - 1) -cmd_map = {} - - -class Command(object): - """Container class for command information.""" - __slots__ = ('name', 'alias', 'func', 'args', 'descr') - FMT_HLP_USAGE = """ -usage: %(prog)s %(name)s %(args)s - %(prog)s %(alias)s %(args)s -""" - - def __init__(self, name, alias, func, args, descr): - """Create a new Command instance. - - Arguments: - - `name` : str - the command name, e.g. ``addalias`` - `alias` : str - the command's short alias, e.g. ``aa`` - `func` : callable - the function to handle the command - `args` : str - argument placeholders, e.g. ``aliasaddress`` - `descr` : str - short description of the command - """ - self.name = name - self.alias = alias - self.func = func - self.args = args - self.descr = descr - - @property - def usage(self): - """the command's usage info.""" - return u'%s %s %s' % (prog, self.name, self.args) - - def help_(self): - """Print the Command's help message to stdout.""" - old_ii = txt_wrpr.initial_indent - old_si = txt_wrpr.subsequent_indent - - txt_wrpr.subsequent_indent = (len(self.name) + 2) * ' ' - w_std(txt_wrpr.fill('%s: %s' % (self.name, self.descr))) - - info = Command.FMT_HLP_USAGE % dict(alias=self.alias, args=self.args, - name=self.name, prog=prog) - w_std(info) - - txt_wrpr.initial_indent = txt_wrpr.subsequent_indent = ' ' - try: - [w_std(txt_wrpr.fill(_(para)) + '\n') for para - in help_msgs[self.name]] - except KeyError: - w_err(1, _(u"Subcommand '%s' is not yet documented." % self.name), - 'see also: vmm(1)') - - -class RunContext(object): - """Contains all information necessary to run a subcommand.""" - __slots__ = ('argc', 'args', 'cget', 'hdlr', 'scmd') - plan_a_b = _(u'Plan A failed ... trying Plan B: %(subcommand)s %(object)s') - - def __init__(self, argv, handler, command): - """Create a new RunContext""" - self.argc = len(argv) - self.args = [unicode(arg, ENCODING) for arg in argv] - self.cget = handler.cfg_dget - self.hdlr = handler - self.scmd = command - - -def alias_add(ctx): - """create a new alias e-mail address""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing alias address and destination.'), - ctx.scmd) - elif ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing destination address.'), ctx.scmd) - ctx.hdlr.alias_add(ctx.args[2].lower(), *ctx.args[3:]) - - -def alias_delete(ctx): - """delete the specified alias e-mail address or one of its destinations""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing alias address.'), ctx.scmd) - elif ctx.argc < 4: - ctx.hdlr.alias_delete(ctx.args[2].lower()) - else: - ctx.hdlr.alias_delete(ctx.args[2].lower(), ctx.args[3:]) - - -def alias_info(ctx): - """show the destination(s) of the specified alias""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing alias address.'), ctx.scmd) - address = ctx.args[2].lower() - try: - _print_aliase_info(address, ctx.hdlr.alias_info(address)) - except VMMError, err: - if err.code is ACCOUNT_EXISTS: - w_err(0, ctx.plan_a_b % {'subcommand': u'userinfo', - 'object': address}) - ctx.scmd = ctx.args[1] = 'userinfo' - user_info(ctx) - elif err.code is RELOCATED_EXISTS: - w_err(0, ctx.plan_a_b % {'subcommand': u'relocatedinfo', - 'object': address}) - ctx.scmd = ctx.args[1] = 'relocatedinfo' - relocated_info(ctx) - else: - raise - - -def aliasdomain_add(ctx): - """create a new alias for an existing domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing alias domain name and destination ' - u'domain name.'), ctx.scmd) - elif ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing destination domain name.'), - ctx.scmd) - ctx.hdlr.aliasdomain_add(ctx.args[2].lower(), ctx.args[3].lower()) - - -def aliasdomain_delete(ctx): - """delete the specified alias domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing alias domain name.'), ctx.scmd) - ctx.hdlr.aliasdomain_delete(ctx.args[2].lower()) - - -def aliasdomain_info(ctx): - """show the destination of the given alias domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing alias domain name.'), ctx.scmd) - try: - _print_aliasdomain_info(ctx.hdlr.aliasdomain_info(ctx.args[2].lower())) - except VMMError, err: - if err.code is ALIASDOMAIN_ISDOMAIN: - w_err(0, ctx.plan_a_b % {'subcommand': u'domaininfo', - 'object': ctx.args[2].lower()}) - ctx.scmd = ctx.args[1] = 'domaininfo' - domain_info(ctx) - else: - raise - - -def aliasdomain_switch(ctx): - """assign the given alias domain to an other domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing alias domain name and destination ' - u'domain name.'), ctx.scmd) - elif ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing destination domain name.'), - ctx.scmd) - ctx.hdlr.aliasdomain_switch(ctx.args[2].lower(), ctx.args[3].lower()) - - -def catchall_add(ctx): - """create a new catchall alias e-mail address""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain and destination.'), - ctx.scmd) - elif ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing destination address.'), ctx.scmd) - ctx.hdlr.catchall_add(ctx.args[2].lower(), *ctx.args[3:]) - - -def catchall_delete(ctx): - """delete the specified destination or all of the catchall destination""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) - elif ctx.argc < 4: - ctx.hdlr.catchall_delete(ctx.args[2].lower()) - else: - ctx.hdlr.catchall_delete(ctx.args[2].lower(), ctx.args[3:]) - - -def catchall_info(ctx): - """show the catchall destination(s) of the specified domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) - address = ctx.args[2].lower() - _print_catchall_info(address, ctx.hdlr.catchall_info(address)) - - -def config_get(ctx): - """show the actual value of the configuration option""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u"Missing option name."), ctx.scmd) - - noop = lambda option: option - opt_formater = { - 'misc.dovecot_version': version_str, - 'domain.quota_bytes': human_size, - } - - option = ctx.args[2].lower() - w_std('%s = %s' % (option, opt_formater.get(option, - noop)(ctx.cget(option)))) - - -def config_set(ctx): - """set a new value for the configuration option""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing option and new value.'), ctx.scmd) - if ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing new configuration value.'), - ctx.scmd) - ctx.hdlr.cfg_set(ctx.args[2].lower(), ctx.args[3]) - - -def configure(ctx): - """start interactive configuration mode""" - if ctx.argc < 3: - ctx.hdlr.configure() - else: - ctx.hdlr.configure(ctx.args[2].lower()) - - -def domain_add(ctx): - """create a new domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) - elif ctx.argc < 4: - ctx.hdlr.domain_add(ctx.args[2].lower()) - else: - ctx.hdlr.domain_add(ctx.args[2].lower(), ctx.args[3]) - if ctx.cget('domain.auto_postmaster'): - w_std(_(u'Creating account for postmaster@%s') % ctx.args[2].lower()) - ctx.scmd = 'useradd' - ctx.args = [prog, ctx.scmd, u'postmaster@' + ctx.args[2].lower()] - ctx.argc = 3 - user_add(ctx) - - -def domain_delete(ctx): - """delete the given domain and all its alias domains""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) - elif ctx.argc < 4: - ctx.hdlr.domain_delete(ctx.args[2].lower()) - elif ctx.args[3].lower() == 'force': - ctx.hdlr.domain_delete(ctx.args[2].lower(), True) - else: - usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % ctx.args[3], - ctx.scmd) - - -def domain_info(ctx): - """display information about the given domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) - if ctx.argc < 4: - details = None - else: - details = ctx.args[3].lower() - if details not in ('accounts', 'aliasdomains', 'aliases', 'full', - 'relocated', 'catchall'): - usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % details, - ctx.scmd) - try: - info = ctx.hdlr.domain_info(ctx.args[2].lower(), details) - except VMMError, err: - if err.code is DOMAIN_ALIAS_EXISTS: - w_err(0, ctx.plan_a_b % {'subcommand': u'aliasdomaininfo', - 'object': ctx.args[2].lower()}) - ctx.scmd = ctx.args[1] = 'aliasdomaininfo' - aliasdomain_info(ctx) - else: - raise - else: - q_limit = u'Storage: %(bytes)s; Messages: %(messages)s' - if not details: - info['bytes'] = human_size(info['bytes']) - info['messages'] = locale.format('%d', info['messages'], - True).decode(ENCODING, 'replace') - info['quota limit/user'] = q_limit % info - _print_info(ctx, info, _(u'Domain')) - else: - info[0]['bytes'] = human_size(info[0]['bytes']) - info[0]['messages'] = locale.format('%d', info[0]['messages'], - True).decode(ENCODING, - 'replace') - info[0]['quota limit/user'] = q_limit % info[0] - _print_info(ctx, info[0], _(u'Domain')) - if details == u'accounts': - _print_list(info[1], _(u'accounts')) - elif details == u'aliasdomains': - _print_list(info[1], _(u'alias domains')) - elif details == u'aliases': - _print_list(info[1], _(u'aliases')) - elif details == u'relocated': - _print_list(info[1], _(u'relocated users')) - elif details == u'catchall': - _print_list(info[1], _(u'catch-all destinations')) - else: - _print_list(info[1], _(u'alias domains')) - _print_list(info[2], _(u'accounts')) - _print_list(info[3], _(u'aliases')) - _print_list(info[4], _(u'relocated users')) - _print_list(info[5], _(u'catch-all destinations')) - - -def domain_quota(ctx): - """update the quota limit of the specified domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain name and storage value.'), - ctx.scmd) - if ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing storage value.'), ctx.scmd) - messages = 0 - force = None - try: - bytes_ = size_in_bytes(ctx.args[3]) - except (ValueError, TypeError): - usage(INVALID_ARGUMENT, _(u"Invalid storage value: '%s'") % - ctx.args[3], ctx.scmd) - if ctx.argc < 5: - pass - elif ctx.argc < 6: - try: - messages = int(ctx.args[4]) - except ValueError: - if ctx.args[4].lower() != 'force': - usage(INVALID_ARGUMENT, - _(u"Neither a valid number of messages nor the keyword " - u"'force': '%s'") % ctx.args[4], ctx.scmd) - force = 'force' - else: - try: - messages = int(ctx.args[4]) - except ValueError: - usage(INVALID_ARGUMENT, - _(u"Not a valid number of messages: '%s'") % ctx.args[4], - ctx.scmd) - if ctx.args[5].lower() != 'force': - usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % ctx.args[5], - ctx.scmd) - force = 'force' - ctx.hdlr.domain_quotalimit(ctx.args[2].lower(), bytes_, messages, force) - - -def domain_services(ctx): - """allow all named service and block the uncredited.""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain name.'), ctx.scmd) - services = [] - force = False - if ctx.argc is 3: - pass - elif ctx.argc is 4: - arg = ctx.args[3].lower() - if arg in SERVICES: - services.append(arg) - elif arg == 'force': - force = True - else: - usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % arg, - ctx.scmd) - else: - services.extend([service.lower() for service in ctx.args[3:-1]]) - arg = ctx.args[-1].lower() - if arg == 'force': - force = True - else: - services.append(arg) - unknown = [service for service in services if service not in SERVICES] - if unknown: - usage(INVALID_ARGUMENT, _(u'Invalid service arguments: %s') % - ' '.join(unknown), ctx.scmd) - ctx.hdlr.domain_services(ctx.args[2].lower(), (None, 'force')[force], - *services) - - -def domain_transport(ctx): - """update the transport of the specified domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain name and new transport.'), - ctx.scmd) - if ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing new transport.'), ctx.scmd) - if ctx.argc < 5: - ctx.hdlr.domain_transport(ctx.args[2].lower(), ctx.args[3]) - else: - force = ctx.args[4].lower() - if force != 'force': - usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % force, - ctx.scmd) - ctx.hdlr.domain_transport(ctx.args[2].lower(), ctx.args[3], force) - - -def domain_note(ctx): - """update the note of the given domain""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing domain name.'), - ctx.scmd) - elif ctx.argc < 4: - note = None - else: - note = ' '.join(ctx.args[3:]) - ctx.hdlr.domain_note(ctx.args[2].lower(), note) - - -def get_user(ctx): - """get the address of the user with the given UID""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing UID.'), ctx.scmd) - _print_info(ctx, ctx.hdlr.user_by_uid(ctx.args[2]), _(u'Account')) - - -def help_(ctx): - """print help messages.""" - if ctx.argc > 2: - hlptpc = ctx.args[2].lower() - if hlptpc in cmd_map: - topic = hlptpc - else: - for scmd in cmd_map.itervalues(): - if scmd.alias == hlptpc: - topic = scmd.name - break - else: - usage(INVALID_ARGUMENT, _(u"Unknown help topic: '%s'") % - ctx.args[2], ctx.scmd) - if topic != u'help': - return cmd_map[topic].help_() - - old_ii = txt_wrpr.initial_indent - old_si = txt_wrpr.subsequent_indent - txt_wrpr.initial_indent = ' ' - # len(max(_overview.iterkeys(), key=len)) #Py25 - txt_wrpr.subsequent_indent = 20 * ' ' - order = cmd_map.keys() - order.sort() - - w_std(_(u'List of available subcommands:') + '\n') - for key in order: - w_std('\n'.join(txt_wrpr.wrap('%-18s %s' % (key, cmd_map[key].descr)))) - - txt_wrpr.initial_indent = old_ii - txt_wrpr.subsequent_indent = old_si - txt_wrpr.initial_indent = '' - - -def list_domains(ctx): - """list all domains / search domains by pattern""" - matching = ctx.argc > 2 - if matching: - gids, domains = ctx.hdlr.domain_list(ctx.args[2].lower()) - else: - gids, domains = ctx.hdlr.domain_list() - _print_domain_list(gids, domains, matching) - - -def list_pwschemes(ctx_unused): - """Prints all usable password schemes and password encoding suffixes.""" - # TODO: Remove trailing colons from keys. - # For now it is to late, the translators has stared their work - keys = (_(u'Usable password schemes:'), _(u'Usable encoding suffixes:')) - old_ii, old_si = txt_wrpr.initial_indent, txt_wrpr.subsequent_indent - txt_wrpr.initial_indent = txt_wrpr.subsequent_indent = '\t' - txt_wrpr.width = txt_wrpr.width - 8 - - for key, value in zip(keys, list_schemes()): - if key.endswith(':'): # who knows … (see TODO above) - #key = key.rpartition(':')[0] - key = key[:-1] # This one is for Py24 - w_std(key, len(key) * '-') - w_std('\n'.join(txt_wrpr.wrap(' '.join(value))), '') - - txt_wrpr.initial_indent, txt_wrpr.subsequent_indent = old_ii, old_si - txt_wrpr.width = txt_wrpr.width + 8 - - -def list_addresses(ctx, limit=None): - """List all addresses / search addresses by pattern. The output can be - limited with TYPE_ACCOUNT, TYPE_ALIAS and TYPE_RELOCATED, which can be - bitwise ORed as a combination. Not specifying a limit is the same as - combining all three.""" - if limit is None: - limit = TYPE_ACCOUNT | TYPE_ALIAS | TYPE_RELOCATED - matching = ctx.argc > 2 - if matching: - gids, addresses = ctx.hdlr.address_list(limit, ctx.args[2].lower()) - else: - gids, addresses = ctx.hdlr.address_list(limit) - _print_address_list(limit, gids, addresses, matching) - - -def list_users(ctx): - """list all user accounts / search user accounts by pattern""" - return list_addresses(ctx, TYPE_ACCOUNT) - - -def list_aliases(ctx): - """list all aliases / search aliases by pattern""" - return list_addresses(ctx, TYPE_ALIAS) - - -def list_relocated(ctx): - """list all relocated records / search relocated records by pattern""" - return list_addresses(ctx, TYPE_RELOCATED) - - -def relocated_add(ctx): - """create a new record for a relocated user""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, - _(u'Missing relocated address and destination.'), ctx.scmd) - elif ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing destination address.'), ctx.scmd) - ctx.hdlr.relocated_add(ctx.args[2].lower(), ctx.args[3]) - - -def relocated_delete(ctx): - """delete the record of the relocated user""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing relocated address.'), ctx.scmd) - ctx.hdlr.relocated_delete(ctx.args[2].lower()) - - -def relocated_info(ctx): - """print information about a relocated user""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing relocated address.'), ctx.scmd) - relocated = ctx.args[2].lower() - try: - _print_relocated_info(addr=relocated, - dest=ctx.hdlr.relocated_info(relocated)) - except VMMError, err: - if err.code is ACCOUNT_EXISTS: - w_err(0, ctx.plan_a_b % {'subcommand': u'userinfo', - 'object': relocated}) - ctx.scmd = ctx.args[1] = 'userinfoi' - user_info(ctx) - elif err.code is ALIAS_EXISTS: - w_err(0, ctx.plan_a_b % {'subcommand': u'aliasinfo', - 'object': relocated}) - ctx.scmd = ctx.args[1] = 'aliasinfo' - alias_info(ctx) - else: - raise - - -def user_add(ctx): - """create a new e-mail user with the given address""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd) - elif ctx.argc < 4: - password = None - else: - password = ctx.args[3] - gen_pass = ctx.hdlr.user_add(ctx.args[2].lower(), password) - if ctx.argc < 4 and gen_pass: - w_std(_(u"Generated password: %s") % gen_pass) - - -def user_delete(ctx): - """delete the specified user""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd) - elif ctx.argc < 4: - ctx.hdlr.user_delete(ctx.args[2].lower()) - elif ctx.args[3].lower() == 'force': - ctx.hdlr.user_delete(ctx.args[2].lower(), True) - else: - usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % ctx.args[3], - ctx.scmd) - - -def user_info(ctx): - """display information about the given address""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd) - if ctx.argc < 4: - details = None - else: - details = ctx.args[3].lower() - if details not in ('aliases', 'du', 'full'): - usage(INVALID_ARGUMENT, _(u"Invalid argument: '%s'") % details, - ctx.scmd) - try: - info = ctx.hdlr.user_info(ctx.args[2].lower(), details) - except VMMError, err: - if err.code is ALIAS_EXISTS: - w_err(0, ctx.plan_a_b % {'subcommand': u'aliasinfo', - 'object': ctx.args[2].lower()}) - ctx.scmd = ctx.args[1] = 'aliasinfo' - alias_info(ctx) - elif err.code is RELOCATED_EXISTS: - w_err(0, ctx.plan_a_b % {'subcommand': u'relocatedinfo', - 'object': ctx.args[2].lower()}) - ctx.scmd = ctx.args[1] = 'relocatedinfo' - relocated_info(ctx) - else: - raise - else: - if details in (None, 'du'): - info['quota storage'] = _format_quota_usage(info['ql_bytes'], - info['uq_bytes'], True, info['ql_domaindefault']) - info['quota messages'] = \ - _format_quota_usage(info['ql_messages'], - info['uq_messages'], - domaindefault=info['ql_domaindefault']) - _print_info(ctx, info, _(u'Account')) - else: - info[0]['quota storage'] = _format_quota_usage(info[0]['ql_bytes'], - info[0]['uq_bytes'], True, info[0]['ql_domaindefault']) - info[0]['quota messages'] = \ - _format_quota_usage(info[0]['ql_messages'], - info[0]['uq_messages'], - domaindefault=info[0]['ql_domaindefault']) - _print_info(ctx, info[0], _(u'Account')) - _print_list(info[1], _(u'alias addresses')) - - -def user_name(ctx): - """set or update the real name for an address""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u"Missing e-mail address and user's name."), - ctx.scmd) - elif ctx.argc < 4: - name = None - else: - name = ctx.args[3] - ctx.hdlr.user_name(ctx.args[2].lower(), name) - - -def user_password(ctx): - """update the password for the given address""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd) - elif ctx.argc < 4: - password = None - else: - password = ctx.args[3] - ctx.hdlr.user_password(ctx.args[2].lower(), password) - - -def user_note(ctx): - """update the note of the given address""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), - ctx.scmd) - elif ctx.argc < 4: - note = None - else: - note = ' '.join(ctx.args[3:]) - ctx.hdlr.user_note(ctx.args[2].lower(), note) - - -def user_quota(ctx): - """update the quota limit for the given address""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing e-mail address and storage value.'), - ctx.scmd) - elif ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing storage value.'), ctx.scmd) - if ctx.args[3] != 'domain': - try: - bytes_ = size_in_bytes(ctx.args[3]) - except (ValueError, TypeError): - usage(INVALID_ARGUMENT, _(u"Invalid storage value: '%s'") % - ctx.args[3], ctx.scmd) - else: - bytes_ = ctx.args[3] - if ctx.argc < 5: - messages = 0 - else: - try: - messages = int(ctx.args[4]) - except ValueError: - usage(INVALID_ARGUMENT, - _(u"Not a valid number of messages: '%s'") % ctx.args[4], - ctx.scmd) - ctx.hdlr.user_quotalimit(ctx.args[2].lower(), bytes_, messages) - - -def user_services(ctx): - """allow all named service and block the uncredited.""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing e-mail address.'), ctx.scmd) - services = [] - if ctx.argc >= 4: - services.extend([service.lower() for service in ctx.args[3:]]) - unknown = [service for service in services if service not in SERVICES] - if unknown and ctx.args[3] != 'domain': - usage(INVALID_ARGUMENT, _(u'Invalid service arguments: %s') % - ' '.join(unknown), ctx.scmd) - ctx.hdlr.user_services(ctx.args[2].lower(), *services) - - -def user_transport(ctx): - """update the transport of the given address""" - if ctx.argc < 3: - usage(EX_MISSING_ARGS, _(u'Missing e-mail address and transport.'), - ctx.scmd) - if ctx.argc < 4: - usage(EX_MISSING_ARGS, _(u'Missing transport.'), ctx.scmd) - ctx.hdlr.user_transport(ctx.args[2].lower(), ctx.args[3]) - - -def usage(errno, errmsg, subcommand=None): - """print usage message for the given command or all commands. - When errno > 0, sys,exit(errno) will interrupt the program. - """ - if subcommand and subcommand in cmd_map: - w_err(errno, _(u"Error: %s") % errmsg, - _(u"usage: ") + cmd_map[subcommand].usage) - - # TP: Please adjust translated words like the original text. - # (It's a table header.) Extract from usage text: - # usage: vmm subcommand arguments - # short long - # subcommand arguments - # - # da domainadd fqdn [transport] - # dd domaindelete fqdn [force] - u_head = _(u"""usage: %s subcommand arguments - short long - subcommand arguments\n""") % prog - order = cmd_map.keys() - order.sort() - w_err(0, u_head) - for key in order: - scmd = cmd_map[key] - w_err(0, ' %-5s %-19s %s' % (scmd.alias, scmd.name, scmd.args)) - w_err(errno, '', _(u"Error: %s") % errmsg) - - -def version(ctx_unused): - """Write version and copyright information to stdout.""" - w_std('%s, %s %s (%s %s)\nPython %s %s %s\n\n%s\n%s %s' % (prog, - # TP: The words 'from', 'version' and 'on' are used in - # the version information, e.g.: - # vmm, version 0.5.2 (from 09/09/09) - # Python 2.5.4 on FreeBSD - _(u'version'), __version__, _(u'from'), - strftime(locale.nl_langinfo(locale.D_FMT), - strptime(__date__, '%Y-%m-%d')).decode(ENCODING, 'replace'), - os.sys.version.split()[0], _(u'on'), os.uname()[0], - __copyright__, prog, - _(u'is free software and comes with ABSOLUTELY NO WARRANTY.'))) - - -def update_cmd_map(): - """Update the cmd_map, after gettext's _ was installed.""" - cmd = Command - cmd_map.update({ - # Account commands - 'getuser': cmd('getuser', 'gu', get_user, 'uid', - _(u'get the address of the user with the given UID')), - 'useradd': cmd('useradd', 'ua', user_add, 'address [password]', - _(u'create a new e-mail user with the given address')), - 'userdelete': cmd('userdelete', 'ud', user_delete, 'address [force]', - _(u'delete the specified user')), - 'userinfo': cmd('userinfo', 'ui', user_info, 'address [details]', - _(u'display information about the given address')), - 'username': cmd('username', 'un', user_name, 'address [name]', - _(u'set, update or delete the real name for an address')), - 'userpassword': cmd('userpassword', 'up', user_password, - 'address [password]', - _(u'update the password for the given address')), - 'userquota': cmd('userquota', 'uq', user_quota, - 'address storage [messages] | address domain', - _(u'update the quota limit for the given address')), - 'userservices': cmd('userservices', 'us', user_services, - 'address [service ...] | address domain', - _(u'enables the specified services and disables all ' - u'not specified services')), - 'usertransport': cmd('usertransport', 'ut', user_transport, - 'address transport | address domain', - _(u'update the transport of the given address')), - 'usernote': cmd('usernote', 'uo', user_note, 'address [note]', - _(u'set, update or delete the note of the given address')), - # Alias commands - 'aliasadd': cmd('aliasadd', 'aa', alias_add, 'address destination ...', - _(u'create a new alias e-mail address with one or more ' - u'destinations')), - 'aliasdelete': cmd('aliasdelete', 'ad', alias_delete, - 'address [destination ...]', - _(u'delete the specified alias e-mail address or one ' - u'of its destinations')), - 'aliasinfo': cmd('aliasinfo', 'ai', alias_info, 'address', - _(u'show the destination(s) of the specified alias')), - # AliasDomain commands - 'aliasdomainadd': cmd('aliasdomainadd', 'ada', aliasdomain_add, - 'fqdn destination', - _(u'create a new alias for an existing domain')), - 'aliasdomaindelete': cmd('aliasdomaindelete', 'add', aliasdomain_delete, - 'fqdn', _(u'delete the specified alias domain')), - 'aliasdomaininfo': cmd('aliasdomaininfo', 'adi', aliasdomain_info, 'fqdn', - _(u'show the destination of the given alias domain')), - 'aliasdomainswitch': cmd('aliasdomainswitch', 'ads', aliasdomain_switch, - 'fqdn destination', _(u'assign the given alias ' - 'domain to an other domain')), - # CatchallAlias commands - 'catchalladd': cmd('catchalladd', 'caa', catchall_add, - 'fqdn destination ...', - _(u'add one or more catch-all destinations for a ' - u'domain')), - 'catchalldelete': cmd('catchalldelete', 'cad', catchall_delete, - 'fqdn [destination ...]', - _(u'delete the specified catch-all destination or all ' - u'of a domain\'s destinations')), - 'catchallinfo': cmd('catchallinfo', 'cai', catchall_info, 'fqdn', - _(u'show the catch-all destination(s) of the ' - u'specified domain')), - # Domain commands - 'domainadd': cmd('domainadd', 'da', domain_add, 'fqdn [transport]', - _(u'create a new domain')), - 'domaindelete': cmd('domaindelete', 'dd', domain_delete, 'fqdn [force]', - _(u'delete the given domain and all its alias domains')), - 'domaininfo': cmd('domaininfo', 'di', domain_info, 'fqdn [details]', - _(u'display information about the given domain')), - 'domainquota': cmd('domainquota', 'dq', domain_quota, - 'fqdn storage [messages] [force]', - _(u'update the quota limit of the specified domain')), - 'domainservices': cmd('domainservices', 'ds', domain_services, - 'fqdn [service ...] [force]', - _(u'enables the specified services and disables all ' - u'not specified services of the given domain')), - 'domaintransport': cmd('domaintransport', 'dt', domain_transport, - 'fqdn transport [force]', - _(u'update the transport of the specified domain')), - 'domainnote': cmd('domainnote', 'do', domain_note, 'fqdn [note]', - _(u'set, update or delete the note of the given domain')), - # List commands - 'listdomains': cmd('listdomains', 'ld', list_domains, '[pattern]', - _(u'list all domains or search for domains by pattern')), - 'listaddresses': cmd('listaddresses', 'll', list_addresses, '[pattern]', - _(u'list all addresses or search for addresses by ' - u'pattern')), - 'listusers': cmd('listusers', 'lu', list_users, '[pattern]', - _(u'list all user accounts or search for accounts by ' - u'pattern')), - 'listaliases': cmd('listaliases', 'la', list_aliases, '[pattern]', - _(u'list all aliases or search for aliases by pattern')), - 'listrelocated': cmd('listrelocated', 'lr', list_relocated, '[pattern]', - _(u'list all relocated users or search for relocated ' - u'users by pattern')), - # Relocated commands - 'relocatedadd': cmd('relocatedadd', 'ra', relocated_add, - 'address newaddress', - _(u'create a new record for a relocated user')), - 'relocateddelete': cmd('relocateddelete', 'rd', relocated_delete, - 'address', - _(u'delete the record of the relocated user')), - 'relocatedinfo': cmd('relocatedinfo', 'ri', relocated_info, 'address', - _(u'print information about a relocated user')), - # cli commands - 'configget': cmd('configget', 'cg', config_get, 'option', - _('show the actual value of the configuration option')), - 'configset': cmd('configset', 'cs', config_set, 'option value', - _('set a new value for the configuration option')), - 'configure': cmd('configure', 'cf', configure, '[section]', - _(u'start interactive configuration mode')), - 'listpwschemes': cmd('listpwschemes', 'lp', list_pwschemes, '', - _(u'lists all usable password schemes and password ' - u'encoding suffixes')), - 'help': cmd('help', 'h', help_, '[subcommand]', - _(u'show a help overview or help for the given subcommand')), - 'version': cmd('version', 'v', version, '', - _(u'show version and copyright information')), - }) - - -def _get_order(ctx): - """returns a tuple with (key, 1||0) tuples. Used by functions, which - get a dict from the handler.""" - order = () - if ctx.scmd == 'domaininfo': - order = ((u'domain name', 0), (u'gid', 1), (u'domain directory', 0), - (u'quota limit/user', 0), (u'active services', 0), - (u'transport', 0), (u'alias domains', 0), (u'accounts', 0), - (u'aliases', 0), (u'relocated', 0), (u'catch-all dests', 0)) - elif ctx.scmd == 'userinfo': - if ctx.argc == 4 and ctx.args[3] != u'aliases' or \ - ctx.cget('account.disk_usage'): - order = ((u'address', 0), (u'name', 0), (u'uid', 1), (u'gid', 1), - (u'home', 0), (u'mail_location', 0), - (u'quota storage', 0), (u'quota messages', 0), - (u'disk usage', 0), (u'transport', 0), (u'smtp', 1), - (u'pop3', 1), (u'imap', 1), (u'sieve', 1)) - else: - order = ((u'address', 0), (u'name', 0), (u'uid', 1), (u'gid', 1), - (u'home', 0), (u'mail_location', 0), - (u'quota storage', 0), (u'quota messages', 0), - (u'transport', 0), (u'smtp', 1), (u'pop3', 1), - (u'imap', 1), (u'sieve', 1)) - elif ctx.scmd == 'getuser': - order = ((u'uid', 1), (u'gid', 1), (u'address', 0)) - return order - - -def _format_quota_usage(limit, used, human=False, domaindefault=False): - """Put quota's limit / usage / percentage in a formatted string.""" - if human: - q_usage = { - 'used': human_size(used), - 'limit': human_size(limit), - } - else: - q_usage = { - 'used': locale.format('%d', used, True).decode(ENCODING, - 'replace'), - 'limit': locale.format('%d', limit, True).decode(ENCODING, - 'replace'), - } - if limit: - q_usage['percent'] = locale.format('%6.2f', 100. / limit * used, True) - else: - q_usage['percent'] = locale.format('%6.2f', 0, True) - # Py25: fmt = format_domain_default if domaindefault else lambda s: s - if domaindefault: - fmt = format_domain_default - else: - fmt = lambda s: s - # TP: e.g.: [ 0.00%] 21.09 KiB/1.00 GiB - return fmt(_(u'[%(percent)s%%] %(used)s/%(limit)s') % q_usage) - - -def _print_info(ctx, info, title): - """Print info dicts.""" - # TP: used in e.g. 'Domain information' or 'Account information' - msg = u'%s %s' % (title, _(u'information')) - w_std(msg, u'-' * len(msg)) - for key, upper in _get_order(ctx): - if upper: - w_std(u'\t%s: %s' % (key.upper().ljust(17, u'.'), info[key])) - else: - w_std(u'\t%s: %s' % (key.title().ljust(17, u'.'), info[key])) - print - note = info.get('note') - if note: - _print_note(note + '\n') - - -def _print_note(note): - msg = _(u'Note') - w_std(msg, u'-' * len(msg)) - old_ii = txt_wrpr.initial_indent - old_si = txt_wrpr.subsequent_indent - txt_wrpr.initial_indent = txt_wrpr.subsequent_indent = '\t' - txt_wrpr.width -= 8 - for para in note.split('\n'): - w_std(txt_wrpr.fill(para)) - txt_wrpr.width += 8 - txt_wrpr.subsequent_indent = old_si - txt_wrpr.initial_indent = old_ii - - -def _print_list(alist, title): - """Print a list.""" - # TP: used in e.g. 'Existing alias addresses' or 'Existing accounts' - msg = u'%s %s' % (_(u'Existing'), title) - w_std(msg, u'-' * len(msg)) - if alist: - if title != _(u'alias domains'): - w_std(*(u'\t%s' % item for item in alist)) - else: - for domain in alist: - if not domain.startswith('xn--'): - w_std(u'\t%s' % domain) - else: - w_std(u'\t%s (%s)' % (domain, domain.decode('idna'))) - print - else: - w_std(_(u'\tNone'), '') - - -def _print_aliase_info(alias, destinations): - """Print the alias address and all its destinations""" - title = _(u'Alias information') - w_std(title, u'-' * len(title)) - w_std(_(u'\tMail for %s will be redirected to:') % alias) - w_std(*(u'\t * %s' % dest for dest in destinations)) - print - - -def _print_catchall_info(domain, destinations): - """Print the catchall destinations of a domain""" - title = _(u'Catch-all information') - w_std(title, u'-' * len(title)) - w_std(_(u'\tMail to unknown local-parts in domain %s will be sent to:') - % domain) - w_std(*(u'\t * %s' % dest for dest in destinations)) - print - - -def _print_relocated_info(**kwargs): - """Print the old and new addresses of a relocated user.""" - title = _(u'Relocated information') - w_std(title, u'-' * len(title)) - w_std(_(u"\tUser '%(addr)s' has moved to '%(dest)s'") % kwargs, '') - - -def _format_domain(domain, main=True): - """format (prefix/convert) the domain name.""" - if domain.startswith('xn--'): - domain = u'%s (%s)' % (domain, domain.decode('idna')) - if main: - return u'\t[+] %s' % domain - return u'\t[-] %s' % domain - - -def _print_domain_list(dids, domains, matching): - """Print a list of (matching) domains/alias domains.""" - if matching: - title = _(u'Matching domains') - else: - title = _(u'Existing domains') - w_std(title, '-' * len(title)) - if domains: - for did in dids: - if domains[did][0] is not None: - w_std(_format_domain(domains[did][0])) - if len(domains[did]) > 1: - w_std(*(_format_domain(a, False) for a in domains[did][1:])) - else: - w_std(_('\tNone')) - print - - -def _print_address_list(which, dids, addresses, matching): - """Print a list of (matching) addresses.""" - _trans = { - TYPE_ACCOUNT: _('user accounts'), - TYPE_ALIAS: _('aliases'), - TYPE_RELOCATED: _('relocated users'), - TYPE_ACCOUNT | TYPE_ALIAS: _('user accounts and aliases'), - TYPE_ACCOUNT | TYPE_RELOCATED: _('user accounts and relocated users'), - TYPE_ALIAS | TYPE_RELOCATED: _('aliases and relocated users'), - TYPE_ACCOUNT | TYPE_ALIAS | TYPE_RELOCATED: _('addresses'), - } - try: - if matching: - title = _(u'Matching %s') % _trans[which] - else: - title = _(u'Existing %s') % _trans[which] - w_std(title, '-' * len(title)) - except KeyError: - raise VMMError(_("Invalid address type for list: '%s'") % which, - INVALID_ARGUMENT) - if addresses: - if which & (which - 1) == 0: - # only one type is requested, so no type indicator - _trans = {TYPE_ACCOUNT: '', TYPE_ALIAS: '', TYPE_RELOCATED: ''} - else: - _trans = { - # TP: the letters 'u', 'a' and 'r' are abbreviations of user, - # alias and relocated user - TYPE_ACCOUNT: _('u'), - TYPE_ALIAS: _('a'), - TYPE_RELOCATED: _('r'), - } - for did in dids: - for addr, atype, aliasdomain in addresses[did]: - if aliasdomain: - leader = '[%s-]' % _trans[atype] - else: - leader = '[%s+]' % _trans[atype] - w_std('\t%s %s' % (leader, addr)) - else: - w_std(_('\tNone')) - print - - -def _print_aliasdomain_info(info): - """Print alias domain information.""" - title = _(u'Alias domain information') - for key in ('alias', 'domain'): - if info[key].startswith('xn--'): - info[key] = u'%s (%s)' % (info[key], info[key].decode('idna')) - w_std(title, '-' * len(title), - _('\tThe alias domain %(alias)s belongs to:\n\t * %(domain)s') % - info, '') - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/common.py --- a/VirtualMailManager/common.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,287 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2010 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.common - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - Some common functions -""" - -import locale -import os -import re -import stat - -from VirtualMailManager import ENCODING -from VirtualMailManager.constants import INVALID_MAIL_LOCATION, \ - NOT_EXECUTABLE, NO_SUCH_BINARY, TYPE_ACCOUNT, TYPE_ALIAS, TYPE_RELOCATED -from VirtualMailManager.errors import VMMError - -VERSION_RE = re.compile(r'^(\d+)\.(\d+)\.(?:(\d+)|(alpha|beta|rc)(\d+))$') - -_version_level = dict(alpha=0xA, beta=0xB, rc=0xC) -_version_cache = {} -_ = lambda msg: msg - - -def expand_path(path): - """Expands paths, starting with ``.`` or ``~``, to an absolute path.""" - if path.startswith('.'): - return os.path.abspath(path) - if path.startswith('~'): - return os.path.expanduser(path) - return path - - -def get_unicode(string): - """Converts `string` to `unicode`, if necessary.""" - if isinstance(string, unicode): - return string - return unicode(string, ENCODING, 'replace') - - -def lisdir(path): - """Checks if `path` is a directory. Doesn't follow symbolic links. - Returns bool. - """ - try: - lstat = os.lstat(path) - except OSError: - return False - return stat.S_ISDIR(lstat.st_mode) - - -def exec_ok(binary): - """Checks if the `binary` exists and if it is executable. - - Throws a `VMMError` if the `binary` isn't a file or is not - executable. - """ - binary = expand_path(binary) - if not os.path.isfile(binary): - raise VMMError(_(u"No such file: '%s'") % get_unicode(binary), - NO_SUCH_BINARY) - if not os.access(binary, os.X_OK): - raise VMMError(_(u"File is not executable: '%s'") % - get_unicode(binary), NOT_EXECUTABLE) - return binary - - -def human_size(size): - """Converts the `size` in bytes in human readable format.""" - if not isinstance(size, (long, int)): - try: - size = long(size) - except ValueError: - raise TypeError("'size' must be a positive long or int.") - if size < 0: - raise ValueError("'size' must be a positive long or int.") - if size < 1024: - return str(size) - # TP: abbreviations of gibibyte, tebibyte kibibyte and mebibyte - prefix_multiply = ((_(u'TiB'), 1 << 40), (_(u'GiB'), 1 << 30), - (_(u'MiB'), 1 << 20), (_(u'KiB'), 1 << 10)) - for prefix, multiply in prefix_multiply: - if size >= multiply: - # TP: e.g.: '%(size)s %(prefix)s' -> '118.30 MiB' - return _(u'%(size)s %(prefix)s') % { - 'size': locale.format('%.2f', float(size) / multiply, - True).decode(ENCODING, 'replace'), - 'prefix': prefix} - - -def size_in_bytes(size): - """Converts the string `size` to a long (size in bytes). - - The string `size` can be suffixed with *b* (bytes), *k* (kilobytes), - *M* (megabytes) or *G* (gigabytes). - """ - if not isinstance(size, basestring) or not size: - raise TypeError('size must be a non empty string.') - if size[-1].upper() in ('B', 'K', 'M', 'G'): - try: - num = int(size[:-1]) - except ValueError: - raise ValueError('Not a valid integer value: %r' % size[:-1]) - unit = size[-1].upper() - if unit == 'B': - return num - elif unit == 'K': - return num << 10L - elif unit == 'M': - return num << 20L - else: - return num << 30L - else: - try: - num = int(size) - except ValueError: - raise ValueError('Not a valid size value: %r' % size) - return num - - -def validate_transport(transport, maillocation): - """Checks if the `transport` is usable for the given `maillocation`. - - Throws a `VMMError` if the chosen `transport` is unable to write - messages in the `maillocation`'s mailbox format. - - Arguments: - - `transport` : VirtualMailManager.transport.Transport - a Transport object - `maillocation` : VirtualMailManager.maillocation.MailLocation - a MailLocation object - """ - if transport.transport in ('virtual', 'virtual:') and \ - not maillocation.postfix: - raise VMMError(_(u"Invalid transport '%(transport)s' for mailbox " - u"format '%(mbfmt)s'.") % - {'transport': transport.transport, - 'mbfmt': maillocation.mbformat}, INVALID_MAIL_LOCATION) - - -def version_hex(version_string): - """Converts a Dovecot version, e.g.: '1.2.3' or '2.0.beta4', to an int. - Raises a `ValueError` if the *version_string* has the wrong™ format. - - version_hex('1.2.3') -> 270548736 - hex(version_hex('1.2.3')) -> '0x10203f00' - """ - global _version_cache - if version_string in _version_cache: - return _version_cache[version_string] - version = 0 - version_mo = VERSION_RE.match(version_string) - if not version_mo: - raise ValueError('Invalid version string: %r' % version_string) - major, minor, patch, level, serial = version_mo.groups() - major = int(major) - minor = int(minor) - if patch: - patch = int(patch) - if serial: - serial = int(serial) - - if major > 0xFF or minor > 0xFF or \ - patch and patch > 0xFF or serial and serial > 0xFF: - raise ValueError('Invalid version string: %r' % version_string) - - version += major << 28 - version += minor << 20 - if patch: - version += patch << 12 - version += _version_level.get(level, 0xF) << 8 - if serial: - version += serial - - _version_cache[version_string] = version - return version - - -def version_str(version): - """Converts a Dovecot version previously converted with version_hex back to - a string. - Raises a `TypeError` if *version* is not an int/long. - Raises a `ValueError` if *version* is an incorrect int version. - """ - global _version_cache - if version in _version_cache: - return _version_cache[version] - if not isinstance(version, (int, long)): - raise TypeError('Argument is not a int/long: %r', version) - major = (version >> 28) & 0xFF - minor = (version >> 20) & 0xFF - patch = (version >> 12) & 0xFF - level = (version >> 8) & 0x0F - serial = version & 0xFF - - levels = dict(zip(_version_level.values(), _version_level.keys())) - if level == 0xF and not serial: - version_string = '%u.%u.%u' % (major, minor, patch) - elif level in levels and not patch: - version_string = '%u.%u.%s%u' % (major, minor, levels[level], serial) - else: - raise ValueError('Invalid version: %r' % hex(version)) - - _version_cache[version] = version_string - return version_string - - -def format_domain_default(domaindata): - """Format info output when the value displayed is the domain default.""" - # TP: [domain default] indicates that a user's setting is the same as - # configured in the user's domain. - # e.g.: [ 0.84%] 42/5,000 [domain default] - return _(u'%s [domain default]') % domaindata - - -def search_addresses(dbh, typelimit=None, lpattern=None, llike=False, - dpattern=None, dlike=False): - """'Search' for addresses by *pattern* in the database. - - The search is limited by *typelimit*, a bitfield with values TYPE_ACCOUNT, - TYPE_ALIAS, TYPE_RELOCATED, or a bitwise OR thereof. If no limit is - specified, all types will be searched. - - *lpattern* may be a local part or a partial local part - starting and/or - ending with a '%' sign. When the *lpattern* starts or ends with a '%' sign - *llike* has to be `True` to perform a wildcard search. To retrieve all - available addresses use the arguments' default values. - - *dpattern* and *dlike* behave analogously for the domain part of an - address, allowing for separate pattern matching: testuser%@example.% - - The return value of this function is a tuple. The first element is a list - of domain IDs sorted alphabetically by the corresponding domain names. The - second element is a dictionary indexed by domain ID, holding lists to - associated addresses. Each address is itself actually a tuple of address, - type, and boolean indicating whether the address stems from an alias - domain. - """ - if typelimit is None: - typelimit = TYPE_ACCOUNT | TYPE_ALIAS | TYPE_RELOCATED - queries = [] - if typelimit & TYPE_ACCOUNT: - queries.append('SELECT gid, local_part, %d AS type FROM users' - % TYPE_ACCOUNT) - if typelimit & TYPE_ALIAS: - queries.append('SELECT DISTINCT gid, address as local_part, ' - '%d AS type FROM alias' % TYPE_ALIAS) - if typelimit & TYPE_RELOCATED: - queries.append('SELECT gid, address as local_part, %d AS type ' - 'FROM relocated' % TYPE_RELOCATED) - sql = "SELECT gid, local_part || '@' || domainname AS address, " - sql += 'type, NOT is_primary AS from_aliasdomain FROM (' - sql += ' UNION '.join(queries) - sql += ') a JOIN domain_name USING (gid)' - nextkw = 'WHERE' - sqlargs = [] - for like, field, pattern in ((dlike, 'domainname', dpattern), - (llike, 'local_part', lpattern)): - if like: - match = 'LIKE' - else: - if not pattern: - continue - match = '=' - sql += ' %s %s %s %%s' % (nextkw, field, match) - sqlargs.append(pattern) - nextkw = 'AND' - sql += ' ORDER BY domainname, local_part' - dbc = dbh.cursor() - dbc.execute(sql, sqlargs) - result = dbc.fetchall() - dbc.close() - - gids = [] - daddrs = {} - for gid, address, addrtype, aliasdomain in result: - if gid not in daddrs: - gids.append(gid) - daddrs[gid] = [] - daddrs[gid].append((address, addrtype, aliasdomain)) - return gids, daddrs - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/config.py --- a/VirtualMailManager/config.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,540 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.config - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - VMM's configuration module for simplified configuration access. -""" - -from ConfigParser import \ - Error, MissingSectionHeaderError, NoOptionError, NoSectionError, \ - ParsingError, RawConfigParser -from cStringIO import StringIO - -from VirtualMailManager.common import VERSION_RE, \ - exec_ok, expand_path, get_unicode, lisdir, size_in_bytes, version_hex -from VirtualMailManager.constants import CONF_ERROR -from VirtualMailManager.errors import ConfigError, VMMError -from VirtualMailManager.maillocation import known_format -from VirtualMailManager.password import verify_scheme as _verify_scheme - -DB_MODULES = ('psycopg2', 'pypgsql') -DB_SSL_MODES = ('allow', 'disabled', 'prefer', 'require', 'verify-ca', - 'verify-full') - -_ = lambda msg: msg - - -class BadOptionError(Error): - """Raised when a option isn't in the format 'section.option'.""" - pass - - -class ConfigValueError(Error): - """Raised when creating or validating of new values fails.""" - pass - - -class NoDefaultError(Error): - """Raised when the requested option has no default value.""" - - def __init__(self, section, option): - Error.__init__(self, 'Option %r in section %r has no default value' % - (option, section)) - - -class LazyConfig(RawConfigParser): - """The **lazy** derivate of the `RawConfigParser`. - - There are two additional getters: - - `pget()` - The polymorphic getter, which returns a option's value with the - appropriate type. - `dget()` - Like `LazyConfig.pget()`, but returns the option's default, from - `LazyConfig._cfg['sectionname']['optionname'].default`, if the - option is not configured in a ini-like configuration file. - - `set()` differs from `RawConfigParser`'s `set()` method. `set()` - takes the `section` and `option` arguments combined to a single - string in the form "section.option". - """ - - def __init__(self): - RawConfigParser.__init__(self) - self._modified = False - # sample _cfg dict. Create your own in your derived class. - self._cfg = { - 'sectionname': { - 'optionname': LazyConfigOption(int, 1, self.getint), - } - } - - def bool_new(self, value): - """Converts the string `value` into a `bool` and returns it. - - | '1', 'on', 'yes' and 'true' will become `True` - | '0', 'off', 'no' and 'false' will become `False` - - Throws a `ConfigValueError` for all other values, except bools. - """ - if isinstance(value, bool): - return value - if value.lower() in self._boolean_states: - return self._boolean_states[value.lower()] - else: - raise ConfigValueError(_(u"Not a boolean: '%s'") % - get_unicode(value)) - - def getboolean(self, section, option): - """Returns the boolean value of the option, in the given - section. - - For a boolean True, the value must be set to '1', 'on', 'yes', - 'true' or True. For a boolean False, the value must set to '0', - 'off', 'no', 'false' or False. - If the option has another value assigned this method will raise - a ValueError. - """ - # if the setting was modified it may be still a boolean value lets see - tmp = self.get(section, option) - if isinstance(tmp, bool): - return tmp - if not tmp.lower() in self._boolean_states: - raise ValueError('Not a boolean: %s' % tmp) - return self._boolean_states[tmp.lower()] - - def _get_section_option(self, section_option): - """splits ``section_option`` (section.option) in two parts and - returns them as list ``[section, option]``, if: - - * it likes the format of ``section_option`` - * the ``section`` is known - * the ``option`` is known - - Else one of the following exceptions will be thrown: - - * `BadOptionError` - * `NoSectionError` - * `NoOptionError` - """ - sect_opt = section_option.lower().split('.') - # TODO: cache it - if len(sect_opt) != 2 or not sect_opt[0] or not sect_opt[1]: - raise BadOptionError(_(u"Bad format: '%s' - expected: " - u"section.option") % - get_unicode(section_option)) - if not sect_opt[0] in self._cfg: - raise NoSectionError(sect_opt[0]) - if not sect_opt[1] in self._cfg[sect_opt[0]]: - raise NoOptionError(sect_opt[1], sect_opt[0]) - return sect_opt - - def items(self, section): - """returns an iterable that returns key, value ``tuples`` from - the given ``section``. - """ - if section in self._sections: # check if the section was parsed - sect = self._sections[section] - elif not section in self._cfg: - raise NoSectionError(section) - else: - return ((k, self._cfg[section][k].default) - for k in self._cfg[section].iterkeys()) - # still here? Get defaults and merge defaults with configured setting - defaults = dict((k, self._cfg[section][k].default) - for k in self._cfg[section].iterkeys()) - defaults.update(sect) - if '__name__' in defaults: - del defaults['__name__'] - return defaults.iteritems() - - def dget(self, option): - """Returns the value of the `option`. - - If the option could not be found in the configuration file, the - configured default value, from ``LazyConfig._cfg`` will be - returned. - - Arguments: - - `option` : string - the configuration option in the form "section.option" - - Throws a `NoDefaultError`, if no default value was passed to - `LazyConfigOption.__init__()` for the `option`. - """ - section, option = self._get_section_option(option) - try: - return self._cfg[section][option].getter(section, option) - except (NoSectionError, NoOptionError): - if not self._cfg[section][option].default is None: # may be False - return self._cfg[section][option].default - else: - raise NoDefaultError(section, option) - - def pget(self, option): - """Returns the value of the `option`.""" - section, option = self._get_section_option(option) - return self._cfg[section][option].getter(section, option) - - def set(self, option, value): - """Set the `value` of the `option`. - - Throws a `ValueError` if `value` couldn't be converted using - `LazyConfigOption.cls`. - """ - # pylint: disable=W0221 - # @pylint: _L A Z Y_ - section, option = self._get_section_option(option) - val = self._cfg[section][option].cls(value) - if self._cfg[section][option].validate: - val = self._cfg[section][option].validate(val) - if not RawConfigParser.has_section(self, section): - self.add_section(section) - RawConfigParser.set(self, section, option, val) - self._modified = True - - def has_section(self, section): - """Checks if `section` is a known configuration section.""" - return section.lower() in self._cfg - - def has_option(self, option): - """Checks if the option (section.option) is a known - configuration option. - """ - # pylint: disable=W0221 - # @pylint: _L A Z Y_ - try: - self._get_section_option(option) - return True - except(BadOptionError, NoSectionError, NoOptionError): - return False - - def sections(self): - """Returns an iterator object for all configuration sections.""" - return self._cfg.iterkeys() - - -class LazyConfigOption(object): - """A simple container class for configuration settings. - - `LazyConfigOption` instances are required by `LazyConfig` instances, - and instances of classes derived from `LazyConfig`, like the - `Config` class. - """ - __slots__ = ('__cls', '__default', '__getter', '__validate') - - def __init__(self, cls, default, getter, validate=None): - """Creates a new `LazyConfigOption` instance. - - Arguments: - - `cls` : type - The class/type of the option's value - `default` - Default value of the option. Use ``None`` if the option should - not have a default value. - `getter` : callable - A method's name of `RawConfigParser` and derived classes, to - get a option's value, e.g. `self.getint`. - `validate` : NoneType or a callable - None or any method, that takes one argument, in order to - check the value, when `LazyConfig.set()` is called. - """ - self.__cls = cls - if not default is None: # enforce the type of the default value - self.__default = self.__cls(default) - else: - self.__default = default - if not callable(getter): - raise TypeError('getter has to be a callable, got a %r' % - getter.__class__.__name__) - self.__getter = getter - if validate and not callable(validate): - raise TypeError('validate has to be callable or None, got a %r' % - validate.__class__.__name__) - self.__validate = validate - - @property - def cls(self): - """The class of the option's value e.g. `str`, `unicode` or `bool`.""" - return self.__cls - - @property - def default(self): - """The option's default value, may be `None`""" - return self.__default - - @property - def getter(self): - """The getter method or function to get the option's value""" - return self.__getter - - @property - def validate(self): - """A method or function to validate the value""" - return self.__validate - - -class Config(LazyConfig): - """This class is for reading vmm's configuration file.""" - - def __init__(self, filename): - """Creates a new Config instance - - Arguments: - - `filename` : str - path to the configuration file - """ - LazyConfig.__init__(self) - self._cfg_filename = filename - self._cfg_file = None - self._missing = {} - - LCO = LazyConfigOption - bool_t = self.bool_new - self._cfg = { - 'account': { - 'delete_directory': LCO(bool_t, False, self.getboolean), - 'directory_mode': LCO(int, 448, self.getint), - 'disk_usage': LCO(bool_t, False, self.getboolean), - 'password_length': LCO(int, 8, self.getint), - 'random_password': LCO(bool_t, False, self.getboolean), - }, - 'bin': { - 'dovecotpw': LCO(str, '/usr/sbin/dovecotpw', self.get, - exec_ok), - 'du': LCO(str, '/usr/bin/du', self.get, exec_ok), - 'postconf': LCO(str, '/usr/sbin/postconf', self.get, exec_ok), - }, - 'database': { - 'host': LCO(str, 'localhost', self.get), - 'module': LCO(str, 'psycopg2', self.get, check_db_module), - 'name': LCO(str, 'mailsys', self.get), - 'pass': LCO(str, None, self.get), - 'port': LCO(int, 5432, self.getint), - 'sslmode': LCO(str, 'prefer', self.get, check_db_ssl_mode), - 'user': LCO(str, None, self.get), - }, - 'domain': { - 'auto_postmaster': LCO(bool_t, True, self.getboolean), - 'delete_directory': LCO(bool_t, False, self.getboolean), - 'directory_mode': LCO(int, 504, self.getint), - 'force_deletion': LCO(bool_t, False, self.getboolean), - 'imap': LCO(bool_t, True, self.getboolean), - 'pop3': LCO(bool_t, True, self.getboolean), - 'sieve': LCO(bool_t, True, self.getboolean), - 'smtp': LCO(bool_t, True, self.getboolean), - 'quota_bytes': LCO(str, '0', self.get_in_bytes, - check_size_value), - 'quota_messages': LCO(int, 0, self.getint), - 'transport': LCO(str, 'dovecot:', self.get), - }, - 'mailbox': { - 'folders': LCO(str, 'Drafts:Sent:Templates:Trash', - self.unicode), - 'format': LCO(str, 'maildir', self.get, check_mailbox_format), - 'root': LCO(str, 'Maildir', self.unicode), - 'subscribe': LCO(bool_t, True, self.getboolean), - }, - 'misc': { - 'base_directory': LCO(str, '/srv/mail', self.get, is_dir), - 'crypt_blowfish_rounds': LCO(int, 5, self.getint), - 'crypt_sha256_rounds': LCO(int, 5000, self.getint), - 'crypt_sha512_rounds': LCO(int, 5000, self.getint), - 'dovecot_version': LCO(str, None, self.hexversion, - check_version_format), - 'password_scheme': LCO(str, 'CRAM-MD5', self.get, - verify_scheme), - }, - } - - def load(self): - """Loads the configuration, read only. - - Raises a ConfigError if the configuration syntax is - invalid. - """ - self._cfg_file = open(self._cfg_filename, 'r') - try: - self.readfp(self._cfg_file) - except (MissingSectionHeaderError, ParsingError), err: - raise ConfigError(str(err), CONF_ERROR) - self._cfg_file.close() - - def check(self): - """Performs a configuration check. - - Raises a ConfigError if settings w/o a default value are missed. - Or some settings have a invalid value. - """ - def iter_dict(): - for section, options in self._missing.iteritems(): - errmsg.write(_(u'* Section: %s\n') % section) - errmsg.writelines(u' %s\n' % option for option in options) - self._missing.clear() - - errmsg = None - self._chk_non_default() - miss_vers = 'misc' in self._missing and \ - 'dovecot_version' in self._missing['misc'] - if self._missing: - errmsg = StringIO() - errmsg.write(_(u'Check of configuration file %s failed.\n') % - self._cfg_filename) - errmsg.write(_(u'Missing options, which have no default value.\n')) - iter_dict() - self._chk_possible_values(miss_vers) - if self._missing: - if not errmsg: - errmsg = StringIO() - errmsg.write(_(u'Check of configuration file %s failed.\n') % - self._cfg_filename) - errmsg.write(_(u'Invalid configuration values.\n')) - else: - errmsg.write('\n' + _(u'Invalid configuration values.\n')) - iter_dict() - if errmsg: - raise ConfigError(errmsg.getvalue(), CONF_ERROR) - - def hexversion(self, section, option): - """Converts the version number (e.g.: 1.2.3) from the *option*'s - value to an int.""" - return version_hex(self.get(section, option)) - - def get_in_bytes(self, section, option): - """Converts the size value (e.g.: 1024k) from the *option*'s - value to a long""" - return size_in_bytes(self.get(section, option)) - - def unicode(self, section, option): - """Returns the value of the `option` from `section`, converted - to Unicode.""" - return get_unicode(self.get(section, option)) - - def _chk_non_default(self): - """Checks all section's options for settings w/o a default - value. Missing items will be stored in _missing. - """ - for section in self._cfg.iterkeys(): - missing = [] - for option, value in self._cfg[section].iteritems(): - if (value.default is None and - not RawConfigParser.has_option(self, section, option)): - missing.append(option) - if missing: - self._missing[section] = missing - - def _chk_possible_values(self, miss_vers): - """Check settings for which the possible values are known.""" - if not miss_vers: - value = self.get('misc', 'dovecot_version') - if not VERSION_RE.match(value): - self._missing['misc'] = ['dovecot_version: ' + - _(u"Not a valid Dovecot version: '%s'") % value] - # section database - db_err = [] - value = self.dget('database.module').lower() - if value not in DB_MODULES: - db_err.append('module: ' + - _(u"Unsupported database module: '%s'") % value) - if value == 'psycopg2': - value = self.dget('database.sslmode') - if value not in DB_SSL_MODES: - db_err.append('sslmode: ' + - _(u"Unknown pgsql SSL mode: '%s'") % value) - if db_err: - self._missing['database'] = db_err - # section mailbox - value = self.dget('mailbox.format') - if not known_format(value): - self._missing['mailbox'] = ['format: ' + - _(u"Unsupported mailbox format: '%s'") % value] - # section domain - try: - value = self.dget('domain.quota_bytes') - except (ValueError, TypeError), err: - self._missing['domain'] = [u'quota_bytes: ' + str(err)] - - -def is_dir(path): - """Check if the expanded path is a directory. When the expanded path - is a directory the expanded path will be returned. Otherwise a - ConfigValueError will be raised. - """ - path = expand_path(path) - if lisdir(path): - return path - raise ConfigValueError(_(u"No such directory: %s") % get_unicode(path)) - - -def check_db_module(module): - """Check if the *module* is a supported pgsql module.""" - if module.lower() in DB_MODULES: - return module - raise ConfigValueError(_(u"Unsupported database module: '%s'") % - get_unicode(module)) - - -def check_db_ssl_mode(ssl_mode): - """Check if the *ssl_mode* is one of the SSL modes, known by pgsql.""" - if ssl_mode in DB_SSL_MODES: - return ssl_mode - raise ConfigValueError(_(u"Unknown pgsql SSL mode: '%s'") % - get_unicode(ssl_mode)) - - -def check_mailbox_format(format): - """ - Check if the mailbox format *format* is supported. When the *format* - is supported it will be returned, otherwise a `ConfigValueError` will - be raised. - """ - format = format.lower() - if known_format(format): - return format - raise ConfigValueError(_(u"Unsupported mailbox format: '%s'") % - get_unicode(format)) - - -def check_size_value(value): - """Check if the size value *value* has the proper format, e.g.: 1024k. - Returns the validated value string if it has the expected format. - Otherwise a `ConfigValueError` will be raised.""" - try: - tmp = size_in_bytes(value) - except (TypeError, ValueError), err: - raise ConfigValueError(_(u"Not a valid size value: '%s'") % - get_unicode(value)) - return value - - -def check_version_format(version_string): - """Check if the *version_string* has the proper format, e.g.: '1.2.3'. - Returns the validated version string if it has the expected format. - Otherwise a `ConfigValueError` will be raised. - """ - if not VERSION_RE.match(version_string): - raise ConfigValueError(_(u"Not a valid Dovecot version: '%s'") % - get_unicode(version_string)) - return version_string - - -def verify_scheme(scheme): - """Checks if the password scheme *scheme* can be accepted and returns - the verified scheme. - """ - try: - scheme, encoding = _verify_scheme(scheme) - except VMMError, err: # 'cast' it - raise ConfigValueError(err.msg) - if not encoding: - return scheme - return '%s.%s' % (scheme, encoding) - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/constants.py --- a/VirtualMailManager/constants.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.constants - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - VirtualMailManager's constants: - * version information - * upper and lower limits MIN_* / MAX_* - * exit codes - * error codes -""" -# version information - -__all__ = ['__author__', '__date__', '__version__'] -AUTHOR = 'Pascal Volk <user+vmm@localhost.localdomain.org>' -RELDATE = '2014-02-01' -VERSION = '0.6.2' -__author__ = AUTHOR -__copyright__ = 'Copyright (c) 2007-2014 %s' % __author__ -__date__ = RELDATE -__version__ = VERSION - - -# limits - -MIN_GID = 70000 -MIN_UID = 70000 - - -# exit codes - -EX_SUCCESS = 0 -EX_MISSING_ARGS = 1 -EX_UNKNOWN_COMMAND = 2 -EX_USER_INTERRUPT = 3 - - -# error codes - -ACCOUNT_AND_ALIAS_PRESENT = 20 -ACCOUNT_EXISTS = 21 -ACCOUNT_MISSING_PASSWORD = 69 -ALIASDOMAIN_EXISTS = 23 -ALIASDOMAIN_ISDOMAIN = 24 -ALIASDOMAIN_NO_DOMDEST = 25 -ALIAS_EXCEEDS_EXPANSION_LIMIT = 27 -ALIAS_EXISTS = 28 -ALIAS_PRESENT = 30 -CONF_ERROR = 31 -CONF_NOFILE = 32 -CONF_NOPERM = 33 -CONF_WRONGPERM = 34 -DATABASE_ERROR = 35 -DOMAINDIR_GROUP_MISMATCH = 36 -DOMAIN_ALIAS_EXISTS = 37 -DOMAIN_EXISTS = 38 -DOMAIN_INVALID = 39 -DOMAIN_NO_NAME = 40 -DOMAIN_TOO_LONG = 41 -FOUND_DOTS_IN_PATH = 42 -INVALID_ADDRESS = 43 -INVALID_ARGUMENT = 44 -INVALID_MAIL_LOCATION = 70 -INVALID_SECTION = 46 -LOCALPART_INVALID = 47 -LOCALPART_TOO_LONG = 48 -MAILDIR_PERM_MISMATCH = 49 -MAILLOCATION_INIT = 50 -NOT_EXECUTABLE = 51 -NO_SUCH_ACCOUNT = 52 -NO_SUCH_ALIAS = 53 -NO_SUCH_ALIASDOMAIN = 54 -NO_SUCH_BINARY = 55 -NO_SUCH_DIRECTORY = 56 -NO_SUCH_DOMAIN = 57 -NO_SUCH_RELOCATED = 58 -RELOCATED_ADDR_DEST_IDENTICAL = 59 -RELOCATED_EXISTS = 60 -UNKNOWN_SERVICE = 65 -VMM_ERROR = 67 -VMM_TOO_MANY_FAILURES = 68 - -# address types - -TYPE_ACCOUNT = 0x1 -TYPE_ALIAS = 0x2 -TYPE_RELOCATED = 0x4 diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/domain.py --- a/VirtualMailManager/domain.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,585 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.domain - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's Domain class to manage e-mail domains. -""" - -import os -import re -from random import choice - -from VirtualMailManager.constants import \ - ACCOUNT_AND_ALIAS_PRESENT, DOMAIN_ALIAS_EXISTS, DOMAIN_EXISTS, \ - DOMAIN_INVALID, DOMAIN_TOO_LONG, NO_SUCH_DOMAIN, VMM_ERROR -from VirtualMailManager.common import validate_transport -from VirtualMailManager.errors import VMMError, DomainError as DomErr -from VirtualMailManager.maillocation import MailLocation -from VirtualMailManager.pycompat import all, any -from VirtualMailManager.quotalimit import QuotaLimit -from VirtualMailManager.serviceset import ServiceSet -from VirtualMailManager.transport import Transport - - -MAILDIR_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz' -RE_DOMAIN = re.compile(r"""^(?:[a-z0-9-]{1,63}\.){1,} # one or more labels - (?:[a-z]{2,} # a ASCII TLD - |xn--[a-z0-9]{4,})$ # or a ACE TLD""", re.X) -_ = lambda msg: msg -cfg_dget = lambda option: None - - -class Domain(object): - """Class to manage e-mail domains.""" - __slots__ = ('_directory', '_gid', '_name', '_qlimit', '_services', - '_transport', '_note', '_dbh', '_new') - - def __init__(self, dbh, domainname): - """Creates a new Domain instance. - - Loads all relevant data from the database, if the domain could be - found. To create a new domain call the methods set_directory() and - set_transport() before save(). - - A DomainError will be thrown when the *domainname* is the name of - an alias domain. - - Arguments: - - `dbh` : pyPgSQL.PgSQL.Connection - a database connection for the database access - `domainname` : basestring - The name of the domain - """ - self._name = check_domainname(domainname) - self._dbh = dbh - self._gid = 0 - self._qlimit = None - self._services = None - self._transport = None - self._directory = None - self._note = None - self._new = True - self._load() - - def _load(self): - """Load information from the database and checks if the domain name - is the primary one. - - Raises a DomainError if Domain._name isn't the primary name of the - domain. - """ - dbc = self._dbh.cursor() - dbc.execute('SELECT dd.gid, qid, ssid, tid, domaindir, is_primary, ' - 'note ' - 'FROM domain_data dd, domain_name dn WHERE domainname = ' - '%s AND dn.gid = dd.gid', (self._name,)) - result = dbc.fetchone() - dbc.close() - if result: - if not result[5]: - raise DomErr(_(u"The domain '%s' is an alias domain.") % - self._name, DOMAIN_ALIAS_EXISTS) - self._gid, self._directory = result[0], result[4] - self._qlimit = QuotaLimit(self._dbh, qid=result[1]) - self._services = ServiceSet(self._dbh, ssid=result[2]) - self._transport = Transport(self._dbh, tid=result[3]) - self._note = result[6] - self._new = False - - def _set_gid(self): - """Sets the ID of the domain - if not set yet.""" - assert self._gid == 0 - dbc = self._dbh.cursor() - dbc.execute("SELECT nextval('domain_gid')") - self._gid = dbc.fetchone()[0] - dbc.close() - - def _check_for_addresses(self): - """Checks dependencies for deletion. Raises a DomainError if there - are accounts, aliases and/or relocated users. - """ - dbc = self._dbh.cursor() - dbc.execute('SELECT ' - '(SELECT count(gid) FROM users WHERE gid = %(gid)u)' - ' as account_count, ' - '(SELECT count(gid) FROM alias WHERE gid = %(gid)u)' - ' as alias_count, ' - '(SELECT count(gid) FROM relocated WHERE gid = %(gid)u)' - ' as relocated_count' - % {'gid': self._gid}) - result = dbc.fetchall() - dbc.close() - result = result[0] - if any(result): - keys = ('account_count', 'alias_count', 'relocated_count') - raise DomErr(_(u'There are %(account_count)u accounts, ' - u'%(alias_count)u aliases and %(relocated_count)u ' - u'relocated users.') % dict(zip(keys, result)), - ACCOUNT_AND_ALIAS_PRESENT) - - def _chk_state(self, must_exist=True): - """Checks the state of the Domain instance and will raise a - VirtualMailManager.errors.DomainError: - - if *must_exist* is `True` and the domain doesn't exist - - or *must_exist* is `False` and the domain exists - """ - if must_exist and self._new: - raise DomErr(_(u"The domain '%s' does not exist.") % self._name, - NO_SUCH_DOMAIN) - elif not must_exist and not self._new: - raise DomErr(_(u"The domain '%s' already exists.") % self._name, - DOMAIN_EXISTS) - - def _update_tables(self, column, value): - """Update table columns in the domain_data table.""" - dbc = self._dbh.cursor() - dbc.execute('UPDATE domain_data SET %s = %%s WHERE gid = %%s' % column, - (value, self._gid)) - if dbc.rowcount > 0: - self._dbh.commit() - dbc.close() - - def _update_tables_ref(self, column, value, force=False): - """Update various columns in the domain_data table. When *force* is - `True`, the corresponding column in the users table will be reset to - NULL. - - Arguments: - - `column` : basestring - Name of the table column. Currently: qid, ssid and tid - `value` : long - The referenced key - `force` : bool - reset existing users. Default: `False` - """ - if column not in ('qid', 'ssid', 'tid'): - raise ValueError('Unknown column: %r' % column) - self._update_tables(column, value) - if force: - dbc = self._dbh.cursor() - dbc.execute('UPDATE users SET %s = NULL WHERE gid = %%s' % column, - (self._gid,)) - if dbc.rowcount > 0: - self._dbh.commit() - dbc.close() - - @property - def gid(self): - """The GID of the Domain.""" - return self._gid - - @property - def name(self): - """The Domain's name.""" - return self._name - - @property - def directory(self): - """The Domain's directory.""" - return self._directory - - @property - def quotalimit(self): - """The Domain's quota limit.""" - return self._qlimit - - @property - def serviceset(self): - """The Domain's serviceset.""" - return self._services - - @property - def transport(self): - """The Domain's transport.""" - return self._transport - - @property - def note(self): - """The Domain's note.""" - return self._note - - def set_directory(self, basedir): - """Set the path value of the Domain's directory, inside *basedir*. - - Argument: - - `basedir` : basestring - The base directory of all domains - """ - self._chk_state(False) - assert self._directory is None - self._set_gid() - self._directory = os.path.join(basedir, choice(MAILDIR_CHARS), - str(self._gid)) - - def set_quotalimit(self, quotalimit): - """Set the quota limit for the new Domain. - - Argument: - - `quotalimit` : VirtualMailManager.quotalimit.QuotaLimit - The quota limit of the new Domain. - """ - self._chk_state(False) - assert isinstance(quotalimit, QuotaLimit) - self._qlimit = quotalimit - - def set_serviceset(self, serviceset): - """Set the services for the new Domain. - - Argument: - - `serviceset` : VirtualMailManager.serviceset.ServiceSet - The service set for the new Domain. - """ - self._chk_state(False) - assert isinstance(serviceset, ServiceSet) - self._services = serviceset - - def set_transport(self, transport): - """Set the transport for the new Domain. - - Argument: - - `transport` : VirtualMailManager.Transport - The transport of the new Domain - """ - self._chk_state(False) - assert isinstance(transport, Transport) - validate_transport(transport, - MailLocation(self._dbh, - mbfmt=cfg_dget('mailbox.format'), - directory=cfg_dget('mailbox.root'))) - self._transport = transport - - def set_note(self, note): - """Set the domain's (optional) note. - - Argument: - - `note` : basestring or None - The note, or None to remove - """ - self._chk_state(False) - assert note is None or isinstance(note, basestring) - self._note = note - - def save(self): - """Stores the new domain in the database.""" - self._chk_state(False) - assert all((self._directory, self._qlimit, self._services, - self._transport)) - dbc = self._dbh.cursor() - dbc.execute('INSERT INTO domain_data (gid, qid, ssid, tid, domaindir, ' - 'note) ' - 'VALUES (%s, %s, %s, %s, %s, %s)', (self._gid, - self._qlimit.qid, self._services.ssid, self._transport.tid, - self._directory, self._note)) - dbc.execute('INSERT INTO domain_name (domainname, gid, is_primary) ' - 'VALUES (%s, %s, TRUE)', (self._name, self._gid)) - self._dbh.commit() - dbc.close() - self._new = False - - def delete(self, force=False): - """Deletes the domain. - - Arguments: - - `force` : bool - force the deletion of all available accounts, aliases and - relocated users. When *force* is `False` and there are accounts, - aliases and/or relocated users a DomainError will be raised. - Default `False` - """ - if not isinstance(force, bool): - raise TypeError('force must be a bool') - self._chk_state() - if not force: - self._check_for_addresses() - dbc = self._dbh.cursor() - for tbl in ('alias', 'users', 'relocated', 'domain_name', - 'domain_data'): - dbc.execute("DELETE FROM %s WHERE gid = %u" % (tbl, self._gid)) - self._dbh.commit() - dbc.close() - self._gid = 0 - self._directory = self._qlimit = self._transport = None - self._services = None - self._new = True - - def update_quotalimit(self, quotalimit, force=False): - """Update the quota limit of the Domain. - - If *force* is `True`, accounts-specific overrides will be reset - for all existing accounts of the domain. Otherwise, the limit - will only affect accounts that use the default. - - Arguments: - - `quotalimit` : VirtualMailManager.quotalimit.QuotaLimit - the new quota limit of the domain. - `force` : bool - enforce new quota limit for all accounts, default `False` - """ - if cfg_dget('misc.dovecot_version') < 0x10102f00: - raise VMMError(_(u'PostgreSQL-based dictionary quota requires ' - u'Dovecot >= v1.1.2.'), VMM_ERROR) - self._chk_state() - assert isinstance(quotalimit, QuotaLimit) - if not force and quotalimit == self._qlimit: - return - self._update_tables_ref('qid', quotalimit.qid, force) - self._qlimit = quotalimit - - def update_serviceset(self, serviceset, force=False): - """Assign a different set of services to the Domain, - - If *force* is `True`, accounts-specific overrides will be reset - for all existing accounts of the domain. Otherwise, the service - set will only affect accounts that use the default. - - Arguments: - `serviceset` : VirtualMailManager.serviceset.ServiceSet - the new set of services - `force` - enforce the serviceset for all accounts, default `False` - """ - self._chk_state() - assert isinstance(serviceset, ServiceSet) - if not force and serviceset == self._services: - return - self._update_tables_ref('ssid', serviceset.ssid, force) - self._services = serviceset - - def update_transport(self, transport, force=False): - """Sets a new transport for the Domain. - - If *force* is `True`, accounts-specific overrides will be reset - for all existing accounts of the domain. Otherwise, the transport - setting will only affect accounts that use the default. - - Arguments: - - `transport` : VirtualMailManager.Transport - the new transport - `force` : bool - enforce new transport setting for all accounts, default `False` - """ - self._chk_state() - assert isinstance(transport, Transport) - if not force and transport == self._transport: - return - validate_transport(transport, - MailLocation(self._dbh, - mbfmt=cfg_dget('mailbox.format'), - directory=cfg_dget('mailbox.root'))) - self._update_tables_ref('tid', transport.tid, force) - self._transport = transport - - def update_note(self, note): - """Sets a new note for the Domain. - - Arguments: - - `transport` : basestring or None - the new note - """ - self._chk_state() - assert note is None or isinstance(note, basestring) - if note == self._note: - return - self._update_tables('note', note) - self._note = note - - def get_info(self): - """Returns a dictionary with information about the domain.""" - self._chk_state() - dbc = self._dbh.cursor() - dbc.execute('SELECT aliasdomains "alias domains", accounts, aliases, ' - 'relocated, catchall "catch-all dests" ' - 'FROM vmm_domain_info WHERE gid = %s', (self._gid,)) - info = dbc.fetchone() - dbc.close() - keys = ('alias domains', 'accounts', 'aliases', 'relocated', - 'catch-all dests') - info = dict(zip(keys, info)) - info['gid'] = self._gid - info['domain name'] = self._name - info['transport'] = self._transport.transport - info['domain directory'] = self._directory - info['bytes'] = self._qlimit.bytes - info['messages'] = self._qlimit.messages - services = self._services.services - services = [s.upper() for s in services if services[s]] - if services: - services.sort() - else: - services.append('None') - info['active services'] = ' '.join(services) - info['note'] = self._note - return info - - def get_accounts(self): - """Returns a list with all accounts of the domain.""" - self._chk_state() - dbc = self._dbh.cursor() - dbc.execute('SELECT local_part from users where gid = %s ORDER BY ' - 'local_part', (self._gid,)) - users = dbc.fetchall() - dbc.close() - accounts = [] - if users: - addr = u'@'.join - _dom = self._name - accounts = [addr((account[0], _dom)) for account in users] - return accounts - - def get_aliases(self): - """Returns a list with all aliases e-mail addresses of the domain.""" - self._chk_state() - dbc = self._dbh.cursor() - dbc.execute('SELECT DISTINCT address FROM alias WHERE gid = %s ORDER ' - 'BY address', (self._gid,)) - addresses = dbc.fetchall() - dbc.close() - aliases = [] - if addresses: - addr = u'@'.join - _dom = self._name - aliases = [addr((alias[0], _dom)) for alias in addresses] - return aliases - - def get_relocated(self): - """Returns a list with all addresses of relocated users.""" - self._chk_state() - dbc = self._dbh.cursor() - dbc.execute('SELECT address FROM relocated WHERE gid = %s ORDER BY ' - 'address', (self._gid,)) - addresses = dbc.fetchall() - dbc.close() - relocated = [] - if addresses: - addr = u'@'.join - _dom = self._name - relocated = [addr((address[0], _dom)) for address in addresses] - return relocated - - def get_catchall(self): - """Returns a list with all catchall e-mail addresses of the domain.""" - self._chk_state() - dbc = self._dbh.cursor() - dbc.execute('SELECT DISTINCT destination FROM catchall WHERE gid = %s ' - 'ORDER BY destination', (self._gid,)) - addresses = dbc.fetchall() - dbc.close() - return addresses - - def get_aliase_names(self): - """Returns a list with all alias domain names of the domain.""" - self._chk_state() - dbc = self._dbh.cursor() - dbc.execute('SELECT domainname FROM domain_name WHERE gid = %s AND ' - 'NOT is_primary ORDER BY domainname', (self._gid,)) - anames = dbc.fetchall() - dbc.close() - aliasdomains = [] - if anames: - aliasdomains = [aname[0] for aname in anames] - return aliasdomains - - -def check_domainname(domainname): - """Returns the validated domain name `domainname`. - - Throws an `DomainError`, if the domain name is too long or doesn't - look like a valid domain name (label.label.label). - - """ - if not RE_DOMAIN.match(domainname): - domainname = domainname.encode('idna') - if len(domainname) > 255: - raise DomErr(_(u'The domain name is too long'), DOMAIN_TOO_LONG) - if not RE_DOMAIN.match(domainname): - raise DomErr(_(u"The domain name '%s' is invalid") % domainname, - DOMAIN_INVALID) - return domainname - - -def get_gid(dbh, domainname): - """Returns the group id of the domain *domainname*. - - If the domain couldn't be found in the database 0 will be returned. - """ - domainname = check_domainname(domainname) - dbc = dbh.cursor() - dbc.execute('SELECT gid FROM domain_name WHERE domainname = %s', - (domainname,)) - gid = dbc.fetchone() - dbc.close() - if gid: - return gid[0] - return 0 - - -def search(dbh, pattern=None, like=False): - """'Search' for domains by *pattern* in the database. - - *pattern* may be a domain name or a partial domain name - starting - and/or ending with a '%' sign. When the *pattern* starts or ends with - a '%' sign *like* has to be `True` to perform a wildcard search. - To retrieve all available domains use the arguments' default values. - - This function returns a tuple with a list and a dict: (order, domains). - The order list contains the domains' gid, alphabetical sorted by the - primary domain name. The domains dict's keys are the gids of the - domains. The value of item is a list. The first list element contains - the primary domain name or `None`. The elements [1:] contains the - names of alias domains. - - Arguments: - - `pattern` : basestring - a (partial) domain name (starting and/or ending with a "%" sign) - `like` : bool - should be `True` when *pattern* starts/ends with a "%" sign - """ - if pattern and not like: - pattern = check_domainname(pattern) - sql = 'SELECT gid, domainname, is_primary FROM domain_name' - if pattern: - if like: - sql += " WHERE domainname LIKE '%s'" % pattern - else: - sql += " WHERE domainname = '%s'" % pattern - sql += ' ORDER BY is_primary DESC, domainname' - dbc = dbh.cursor() - dbc.execute(sql) - result = dbc.fetchall() - dbc.close() - - gids = [domain[0] for domain in result if domain[2]] - domains = {} - for gid, domain, is_primary in result: - if is_primary: - if not gid in domains: - domains[gid] = [domain] - else: - domains[gid].insert(0, domain) - else: - if gid in gids: - if gid in domains: - domains[gid].append(domain) - else: - domains[gid] = [domain] - else: - gids.append(gid) - domains[gid] = [None, domain] - return gids, domains - -del _, cfg_dget diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/emailaddress.py --- a/VirtualMailManager/emailaddress.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2008 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.emailaddress - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's EmailAddress class to handle e-mail addresses. -""" -import re - -from VirtualMailManager.domain import check_domainname, get_gid -from VirtualMailManager.constants import \ - DOMAIN_NO_NAME, INVALID_ADDRESS, LOCALPART_INVALID, LOCALPART_TOO_LONG, \ - DOMAIN_INVALID -from VirtualMailManager.errors import DomainError, EmailAddressError as EAErr - - -RE_LOCALPART = re.compile(r"[^\w!#$%&'\*\+-\.\/=?^_`{\|}~]") -_ = lambda msg: msg - - -class EmailAddress(object): - """Simple class for validated e-mail addresses.""" - __slots__ = ('_localpart', '_domainname') - - def __init__(self, address, _validate=True): - """Creates a new instance from the string/unicode ``address``.""" - assert isinstance(address, basestring) - self._localpart = None - self._domainname = None - if _validate: - self._chk_address(address) - - @property - def localpart(self): - """The local-part of the address *local-part@domain*""" - return self._localpart - - @property - def domainname(self): - """The domain part of the address *local-part@domain*""" - return self._domainname - - def __eq__(self, other): - if isinstance(other, self.__class__): - return self._localpart == other._localpart and \ - self._domainname == other._domainname - return NotImplemented - - def __ne__(self, other): - if isinstance(other, self.__class__): - return self._localpart != other._localpart or \ - self._domainname != other._domainname - return NotImplemented - - def __hash__(self): - return hash((self._localpart.lower(), self._domainname.lower())) - - def __repr__(self): - return "EmailAddress('%s@%s')" % (self._localpart, self._domainname) - - def __str__(self): - return '%s@%s' % (self._localpart, self._domainname) - - def _chk_address(self, address): - """Checks if the string ``address`` could be used for an e-mail - address. If so, it will assign the corresponding values to the - attributes `_localpart` and `_domainname`.""" - parts = address.split('@') - p_len = len(parts) - if p_len < 2: - raise EAErr(_(u"Missing the '@' sign in address: '%s'") % address, - INVALID_ADDRESS) - elif p_len > 2: - raise EAErr(_(u"Too many '@' signs in address: '%s'") % address, - INVALID_ADDRESS) - if not parts[0]: - raise EAErr(_(u"Missing local-part in address: '%s'") % address, - LOCALPART_INVALID) - if not parts[1]: - raise EAErr(_(u"Missing domain name in address: '%s'") % address, - DOMAIN_NO_NAME) - self._localpart = check_localpart(parts[0]) - self._domainname = check_domainname(parts[1]) - - -class DestinationEmailAddress(EmailAddress): - """Provides additionally the domains group ID - when the domain is known - in the database.""" - __slots__ = ('_gid', '_localhost') - - def __init__(self, address, dbh, _validate=False): - """Creates a new DestinationEmailAddress instance - - Arguments: - - `address`: string/unicode - a e-mail address like user@example.com - `dbh`: pyPgSQL.PgSQL.Connection/pyPgSQL.PgSQL.connection - a database connection for the database access - """ - super(DestinationEmailAddress, self).__init__(address, _validate) - self._localhost = False - if not _validate: - try: - self._chk_address(address) - except DomainError, err: - if err.code is DOMAIN_INVALID and \ - address.split('@')[1] == 'localhost': - self._localhost = True - self._domainname = 'localhost' - else: - raise - self._gid = 0 - if not self._localhost: - self._find_domain(dbh) - else: - self._localpart = self._localpart.lower() - - def _find_domain(self, dbh): - """Checks if the domain is known""" - self._gid = get_gid(dbh, self._domainname) - if self._gid: - self._localpart = self._localpart.lower() - - @property - def at_localhost(self): - """True when the address is something@localhost.""" - return self._localhost - - @property - def gid(self): - """The domains group ID. 0 if the domain is not known.""" - return self._gid - - -def check_localpart(localpart): - """Returns the validated local-part `localpart`. - - Throws a `EmailAddressError` if the local-part is too long or contains - invalid characters. - """ - if len(localpart) > 64: - raise EAErr(_(u"The local-part '%s' is too long.") % localpart, - LOCALPART_TOO_LONG) - invalid_chars = set(RE_LOCALPART.findall(localpart)) - if invalid_chars: - i_chars = u''.join((u'"%s" ' % c for c in invalid_chars)) - raise EAErr(_(u"The local-part '%(l_part)s' contains invalid " - u"characters: %(i_chars)s") % {'l_part': localpart, - 'i_chars': i_chars}, LOCALPART_INVALID) - return localpart - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/errors.py --- a/VirtualMailManager/errors.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,71 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.errors - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - VMM's Exception classes -""" - - -class VMMError(Exception): - """Exception base class for VirtualMailManager exceptions""" - - def __init__(self, msg, code): - Exception.__init__(self, msg) - self.msg = msg - self.code = int(code) - - def __repr__(self): - return '%s(%r, %r)' % (self.__class__.__name__, self.msg, self.code) - - -class ConfigError(VMMError): - """Exception class for configuration exceptions""" - pass - - -class PermissionError(VMMError): - """Exception class for permissions exceptions""" - pass - - -class NotRootError(VMMError): - """Exception class for non-root exceptions""" - pass - - -class DomainError(VMMError): - """Exception class for Domain exceptions""" - pass - - -class AliasDomainError(VMMError): - """Exception class for AliasDomain exceptions""" - pass - - -class AccountError(VMMError): - """Exception class for Account exceptions""" - pass - - -class AliasError(VMMError): - """Exception class for Alias exceptions""" - pass - - -class EmailAddressError(VMMError): - """Exception class for EmailAddress exceptions""" - pass - - -class MailLocationError(VMMError): - """Exception class for MailLocation exceptions""" - pass - - -class RelocatedError(VMMError): - """Exception class for Relocated exceptions""" - pass diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/ext/__init__.py --- a/VirtualMailManager/ext/__init__.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2008 - 2014, Pascal Volk -# See COPYING for distribution information. -# package placeholder -# -# EOF diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/ext/postconf.py --- a/VirtualMailManager/ext/postconf.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2008 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.ext.postconf - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Wrapper class for Postfix's postconf. - Postconf instances can be used to read actual values of configuration - parameters or edit the value of a configuration parameter. - - postconf.read(parameter) -> value - postconf.edit(parameter, value) -""" - -import re -from subprocess import Popen, PIPE - -from VirtualMailManager.errors import VMMError -from VirtualMailManager.constants import VMM_ERROR - -_ = lambda msg: msg - - -class Postconf(object): - """Wrapper class for Postfix's postconf.""" - __slots__ = ('_bin', '_val') - _parameter_re = re.compile(r'^\w+$') - _variables_re = re.compile(r'\$\b\w+\b') - - def __init__(self, postconf_bin): - """Creates a new Postconf instance. - - Argument: - - `postconf_bin` : str - absolute path to the Postfix postconf binary. - """ - self._bin = postconf_bin - self._val = '' - - def edit(self, parameter, value): - """Set the `parameter`'s value to `value`. - - Arguments: - - `parameter` : str - the name of a Postfix configuration parameter - `value` : str - the parameter's new value. - """ - self._check_parameter(parameter) - stderr = Popen((self._bin, '-e', parameter + '=' + str(value)), - stderr=PIPE).communicate()[1] - if stderr: - raise VMMError(stderr.strip(), VMM_ERROR) - - def read(self, parameter, expand_vars=True): - """Returns the parameters value. - - If expand_vars is True (default), all variables in the value will be - expanded: - e.g. mydestination: mail.example.com, localhost.example.com, localhost - Otherwise the value may contain one or more variables. - e.g. mydestination: $myhostname, localhost.$mydomain, localhost - - Arguments: - - `parameter` : str - the name of a Postfix configuration parameter. - `expand_vars` : bool - indicates if variables should be expanded or not, default True - """ - self._check_parameter(parameter) - self._val = self._read(parameter) - if expand_vars: - self._expand_vars() - return self._val - - def _check_parameter(self, parameter): - """Check that the `parameter` looks like a configuration parameter. - If not, a VMMError will be raised.""" - if not self.__class__._parameter_re.match(parameter): - raise VMMError(_(u"The value '%s' does not look like a valid " - u"Postfix configuration parameter name.") % - parameter, VMM_ERROR) - - def _expand_vars(self): - """Expand the $variables in self._val to their values.""" - while True: - pvars = set(self.__class__._variables_re.findall(self._val)) - if not pvars: - break - if len(pvars) > 1: - self._expand_multi_vars(self._read_multi(pvars)) - continue - pvars = pvars.pop() - self._val = self._val.replace(pvars, self._read(pvars[1:])) - - def _expand_multi_vars(self, old_new): - """Replace all $vars in self._val with their values.""" - for old, new in old_new.iteritems(): - self._val = self._val.replace('$' + old, new) - - def _read(self, parameter): - """Ask postconf for the value of a single configuration parameter.""" - stdout, stderr = Popen([self._bin, '-h', parameter], stdout=PIPE, - stderr=PIPE).communicate() - if stderr: - raise VMMError(stderr.strip(), VMM_ERROR) - return stdout.strip() - - def _read_multi(self, parameters): - """Ask postconf for multiple configuration parameters. Returns a dict - parameter: value items.""" - cmd = [self._bin] - cmd.extend(parameter[1:] for parameter in parameters) - stdout, stderr = Popen(cmd, stdout=PIPE, stderr=PIPE).communicate() - if stderr: - raise VMMError(stderr.strip(), VMM_ERROR) - par_val = {} - for line in stdout.splitlines(): - par, val = line.split(' = ') - par_val[par] = val - return par_val - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/handler.py --- a/VirtualMailManager/handler.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,914 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2007 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.handler - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - A wrapper class. It wraps round all other classes and does some - dependencies checks. - - Additionally it communicates with the PostgreSQL database, creates - or deletes directories of domains or users. -""" - -import os -import re - -from shutil import rmtree -from subprocess import Popen, PIPE - -from VirtualMailManager.account import Account -from VirtualMailManager.alias import Alias -from VirtualMailManager.aliasdomain import AliasDomain -from VirtualMailManager.catchall import CatchallAlias -from VirtualMailManager.common import exec_ok, lisdir -from VirtualMailManager.config import Config as Cfg -from VirtualMailManager.constants import MIN_GID, MIN_UID, \ - ACCOUNT_EXISTS, ALIAS_EXISTS, CONF_NOFILE, CONF_NOPERM, CONF_WRONGPERM, \ - DATABASE_ERROR, DOMAINDIR_GROUP_MISMATCH, DOMAIN_INVALID, \ - FOUND_DOTS_IN_PATH, INVALID_ARGUMENT, MAILDIR_PERM_MISMATCH, \ - NOT_EXECUTABLE, NO_SUCH_ACCOUNT, NO_SUCH_ALIAS, NO_SUCH_BINARY, \ - NO_SUCH_DIRECTORY, NO_SUCH_RELOCATED, RELOCATED_EXISTS, UNKNOWN_SERVICE, \ - VMM_ERROR, LOCALPART_INVALID, TYPE_ACCOUNT, TYPE_ALIAS, TYPE_RELOCATED -from VirtualMailManager.domain import Domain -from VirtualMailManager.emailaddress import DestinationEmailAddress, \ - EmailAddress, RE_LOCALPART -from VirtualMailManager.errors import \ - DomainError, NotRootError, PermissionError, VMMError -from VirtualMailManager.mailbox import new as new_mailbox -from VirtualMailManager.pycompat import all, any -from VirtualMailManager.quotalimit import QuotaLimit -from VirtualMailManager.relocated import Relocated -from VirtualMailManager.serviceset import ServiceSet, SERVICES -from VirtualMailManager.transport import Transport - - -_ = lambda msg: msg -_db_mod = None - -CFG_FILE = 'vmm.cfg' -CFG_PATH = '/root:/usr/local/etc:/etc' -RE_DOMAIN_SEARCH = """^[a-z0-9-\.]+$""" -OTHER_TYPES = { - TYPE_ACCOUNT: (_(u'an account'), ACCOUNT_EXISTS), - TYPE_ALIAS: (_(u'an alias'), ALIAS_EXISTS), - TYPE_RELOCATED: (_(u'a relocated user'), RELOCATED_EXISTS), -} - - -class Handler(object): - """Wrapper class to simplify the access on all the stuff from - VirtualMailManager""" - __slots__ = ('_cfg', '_cfg_fname', '_db_connect', '_dbh', '_warnings') - - def __init__(self, skip_some_checks=False): - """Creates a new Handler instance. - - ``skip_some_checks`` : bool - When a derived class knows how to handle all checks this - argument may be ``True``. By default it is ``False`` and - all checks will be performed. - - Throws a NotRootError if your uid is greater 0. - """ - self._cfg_fname = '' - self._warnings = [] - self._cfg = None - self._dbh = None - self._db_connect = None - - if os.geteuid(): - raise NotRootError(_(u"You are not root.\n\tGood bye!\n"), - CONF_NOPERM) - if self._check_cfg_file(): - self._cfg = Cfg(self._cfg_fname) - self._cfg.load() - if not skip_some_checks: - self._cfg.check() - self._chkenv() - self._set_db_connect() - - def _find_cfg_file(self): - """Search the CFG_FILE in CFG_PATH. - Raise a VMMError when no vmm.cfg could be found. - """ - for path in CFG_PATH.split(':'): - tmp = os.path.join(path, CFG_FILE) - if os.path.isfile(tmp): - self._cfg_fname = tmp - break - if not self._cfg_fname: - raise VMMError(_(u"Could not find '%(cfg_file)s' in: " - u"'%(cfg_path)s'") % {'cfg_file': CFG_FILE, - 'cfg_path': CFG_PATH}, CONF_NOFILE) - - def _check_cfg_file(self): - """Checks the configuration file, returns bool""" - self._find_cfg_file() - fstat = os.stat(self._cfg_fname) - fmode = int(oct(fstat.st_mode & 0777)) - if fmode % 100 and fstat.st_uid != fstat.st_gid or \ - fmode % 10 and fstat.st_uid == fstat.st_gid: - # TP: Please keep the backticks around the command. `chmod 0600 …` - raise PermissionError(_(u"wrong permissions for '%(file)s': " - u"%(perms)s\n`chmod 0600 %(file)s` would " - u"be great.") % {'file': self._cfg_fname, - 'perms': fmode}, CONF_WRONGPERM) - else: - return True - - def _chkenv(self): - """Make sure our base_directory is a directory and that all - required executables exists and are executable. - If not, a VMMError will be raised""" - dir_created = False - basedir = self._cfg.dget('misc.base_directory') - if not os.path.exists(basedir): - old_umask = os.umask(0006) - os.makedirs(basedir, 0771) - os.chown(basedir, 0, 0) - os.umask(old_umask) - dir_created = True - if not dir_created and not lisdir(basedir): - raise VMMError(_(u"'%(path)s' is not a directory.\n(%(cfg_file)s: " - u"section 'misc', option 'base_directory')") % - {'path': basedir, 'cfg_file': self._cfg_fname}, - NO_SUCH_DIRECTORY) - for opt, val in self._cfg.items('bin'): - try: - exec_ok(val) - except VMMError, err: - if err.code in (NO_SUCH_BINARY, NOT_EXECUTABLE): - raise VMMError(err.msg + _(u"\n(%(cfg_file)s: section " - u"'bin', option '%(option)s')") % - {'cfg_file': self._cfg_fname, - 'option': opt}, err.code) - else: - raise - - def _set_db_connect(self): - """check which module to use and set self._db_connect""" - global _db_mod - if self._cfg.dget('database.module').lower() == 'psycopg2': - try: - _db_mod = __import__('psycopg2') - except ImportError: - raise VMMError(_(u"Unable to import database module '%s'.") % - 'psycopg2', VMM_ERROR) - self._db_connect = self._psycopg2_connect - else: - try: - tmp = __import__('pyPgSQL', globals(), locals(), ['PgSQL']) - except ImportError: - raise VMMError(_(u"Unable to import database module '%s'.") % - 'pyPgSQL', VMM_ERROR) - _db_mod = tmp.PgSQL - self._db_connect = self._pypgsql_connect - - def _pypgsql_connect(self): - """Creates a pyPgSQL.PgSQL.connection instance.""" - if self._dbh is None or (isinstance(self._dbh, _db_mod.Connection) and - not self._dbh._isOpen): - try: - self._dbh = _db_mod.connect( - database=self._cfg.dget('database.name'), - user=self._cfg.pget('database.user'), - host=self._cfg.dget('database.host'), - port=self._cfg.dget('database.port'), - password=self._cfg.pget('database.pass'), - client_encoding='utf8', unicode_results=True) - dbc = self._dbh.cursor() - dbc.execute("SET NAMES 'UTF8'") - dbc.close() - except _db_mod.libpq.DatabaseError, err: - raise VMMError(str(err), DATABASE_ERROR) - - def _psycopg2_connect(self): - """Return a new psycopg2 connection object.""" - if self._dbh is None or \ - (isinstance(self._dbh, _db_mod.extensions.connection) and - self._dbh.closed): - try: - self._dbh = _db_mod.connect( - host=self._cfg.dget('database.host'), - sslmode=self._cfg.dget('database.sslmode'), - port=self._cfg.dget('database.port'), - database=self._cfg.dget('database.name'), - user=self._cfg.pget('database.user'), - password=self._cfg.pget('database.pass')) - self._dbh.set_client_encoding('utf8') - _db_mod.extensions.register_type(_db_mod.extensions.UNICODE) - dbc = self._dbh.cursor() - dbc.execute("SET NAMES 'UTF8'") - dbc.close() - except _db_mod.DatabaseError, err: - raise VMMError(str(err), DATABASE_ERROR) - - def _chk_other_address_types(self, address, exclude): - """Checks if the EmailAddress *address* is known as `TYPE_ACCOUNT`, - `TYPE_ALIAS` or `TYPE_RELOCATED`, but not as the `TYPE_*` specified - by *exclude*. If the *address* is known as one of the `TYPE_*`s - the according `TYPE_*` constant will be returned. Otherwise 0 will - be returned.""" - assert exclude in (TYPE_ACCOUNT, TYPE_ALIAS, TYPE_RELOCATED) and \ - isinstance(address, EmailAddress) - if exclude is not TYPE_ACCOUNT: - account = Account(self._dbh, address) - if account: - return TYPE_ACCOUNT - if exclude is not TYPE_ALIAS: - alias = Alias(self._dbh, address) - if alias: - return TYPE_ALIAS - if exclude is not TYPE_RELOCATED: - relocated = Relocated(self._dbh, address) - if relocated: - return TYPE_RELOCATED - return 0 - - def _is_other_address(self, address, exclude): - """Checks if *address* is known for an Account (TYPE_ACCOUNT), - Alias (TYPE_ALIAS) or Relocated (TYPE_RELOCATED), except for - *exclude*. Returns `False` if the address is not known for other - types. - - Raises a `VMMError` if the address is known. - """ - other = self._chk_other_address_types(address, exclude) - if not other: - return False - # TP: %(a_type)s will be one of: 'an account', 'an alias' or - # 'a relocated user' - msg = _(u"There is already %(a_type)s with the address '%(address)s'.") - raise VMMError(msg % {'a_type': OTHER_TYPES[other][0], - 'address': address}, OTHER_TYPES[other][1]) - - def _get_account(self, address): - """Return an Account instances for the given address (str).""" - address = EmailAddress(address) - self._db_connect() - return Account(self._dbh, address) - - def _get_alias(self, address): - """Return an Alias instances for the given address (str).""" - address = EmailAddress(address) - self._db_connect() - return Alias(self._dbh, address) - - def _get_catchall(self, domain): - """Return a CatchallAlias instances for the given domain (str).""" - self._db_connect() - return CatchallAlias(self._dbh, domain) - - def _get_relocated(self, address): - """Return a Relocated instances for the given address (str).""" - address = EmailAddress(address) - self._db_connect() - return Relocated(self._dbh, address) - - def _get_domain(self, domainname): - """Return a Domain instances for the given domain name (str).""" - self._db_connect() - return Domain(self._dbh, domainname) - - def _get_disk_usage(self, directory): - """Estimate file space usage for the given directory. - - Arguments: - - `directory` : basestring - The directory to summarize recursively disk usage for - """ - if lisdir(directory): - return Popen([self._cfg.dget('bin.du'), "-hs", directory], - stdout=PIPE).communicate()[0].split('\t')[0] - else: - self._warnings.append(_('No such directory: %s') % directory) - return 0 - - def _make_domain_dir(self, domain): - """Create a directory for the `domain` and its accounts.""" - cwd = os.getcwd() - hashdir, domdir = domain.directory.split(os.path.sep)[-2:] - dir_created = False - os.chdir(self._cfg.dget('misc.base_directory')) - old_umask = os.umask(0022) - if not os.path.exists(hashdir): - os.mkdir(hashdir, 0711) - os.chown(hashdir, 0, 0) - dir_created = True - if not dir_created and not lisdir(hashdir): - raise VMMError(_(u"'%s' is not a directory.") % hashdir, - NO_SUCH_DIRECTORY) - if os.path.exists(domain.directory): - raise VMMError(_(u"The file/directory '%s' already exists.") % - domain.directory, VMM_ERROR) - os.mkdir(os.path.join(hashdir, domdir), - self._cfg.dget('domain.directory_mode')) - os.chown(domain.directory, 0, domain.gid) - os.umask(old_umask) - os.chdir(cwd) - - def _make_home(self, account): - """Create a home directory for the new Account *account*.""" - domdir = account.domain.directory - if not lisdir(domdir): - self._make_domain_dir(account.domain) - os.umask(0007) - uid = account.uid - os.chdir(domdir) - os.mkdir('%s' % uid, self._cfg.dget('account.directory_mode')) - os.chown('%s' % uid, uid, account.gid) - - def _make_account_dirs(self, account): - """Create all necessary directories for the account.""" - oldpwd = os.getcwd() - self._make_home(account) - mailbox = new_mailbox(account) - mailbox.create() - folders = self._cfg.dget('mailbox.folders').split(':') - if any(folders): - bad = mailbox.add_boxes(folders, - self._cfg.dget('mailbox.subscribe')) - if bad: - self._warnings.append(_(u"Skipped mailbox folders:") + - '\n\t- ' + '\n\t- '.join(bad)) - os.chdir(oldpwd) - - def _delete_home(self, domdir, uid, gid): - """Delete a user's home directory. - - Arguments: - - `domdir` : basestring - The directory of the domain the user belongs to - (commonly AccountObj.domain.directory) - `uid` : int/long - The user's UID (commonly AccountObj.uid) - `gid` : int/long - The user's GID (commonly AccountObj.gid) - """ - assert all(isinstance(xid, (long, int)) for xid in (uid, gid)) and \ - isinstance(domdir, basestring) - if uid < MIN_UID or gid < MIN_GID: - raise VMMError(_(u"UID '%(uid)u' and/or GID '%(gid)u' are less " - u"than %(min_uid)u/%(min_gid)u.") % {'uid': uid, - 'gid': gid, 'min_gid': MIN_GID, 'min_uid': MIN_UID}, - MAILDIR_PERM_MISMATCH) - if domdir.count('..'): - raise VMMError(_(u'Found ".." in domain directory path: %s') % - domdir, FOUND_DOTS_IN_PATH) - if not lisdir(domdir): - raise VMMError(_(u"No such directory: %s") % domdir, - NO_SUCH_DIRECTORY) - os.chdir(domdir) - userdir = '%s' % uid - if not lisdir(userdir): - self._warnings.append(_(u"No such directory: %s") % - os.path.join(domdir, userdir)) - return - mdstat = os.lstat(userdir) - if (mdstat.st_uid, mdstat.st_gid) != (uid, gid): - raise VMMError(_(u'Detected owner/group mismatch in home ' - u'directory.'), MAILDIR_PERM_MISMATCH) - rmtree(userdir, ignore_errors=True) - - def _delete_domain_dir(self, domdir, gid): - """Delete a domain's directory. - - Arguments: - - `domdir` : basestring - The domain's directory (commonly DomainObj.directory) - `gid` : int/long - The domain's GID (commonly DomainObj.gid) - """ - assert isinstance(domdir, basestring) and isinstance(gid, (long, int)) - if gid < MIN_GID: - raise VMMError(_(u"GID '%(gid)u' is less than '%(min_gid)u'.") % - {'gid': gid, 'min_gid': MIN_GID}, - DOMAINDIR_GROUP_MISMATCH) - if domdir.count('..'): - raise VMMError(_(u'Found ".." in domain directory path: %s') % - domdir, FOUND_DOTS_IN_PATH) - if not lisdir(domdir): - self._warnings.append(_('No such directory: %s') % domdir) - return - dirst = os.lstat(domdir) - if dirst.st_gid != gid: - raise VMMError(_(u'Detected group mismatch in domain directory: ' - u'%s') % domdir, DOMAINDIR_GROUP_MISMATCH) - rmtree(domdir, ignore_errors=True) - - def has_warnings(self): - """Checks if warnings are present, returns bool.""" - return bool(len(self._warnings)) - - def get_warnings(self): - """Returns a list with all available warnings and resets all - warnings. - """ - ret_val = self._warnings[:] - del self._warnings[:] - return ret_val - - def cfg_dget(self, option): - """Get the configured value of the *option* (section.option). - When the option was not configured its default value will be - returned.""" - return self._cfg.dget(option) - - def cfg_pget(self, option): - """Get the configured value of the *option* (section.option).""" - return self._cfg.pget(option) - - def cfg_install(self): - """Installs the cfg_dget method as ``cfg_dget`` into the built-in - namespace.""" - import __builtin__ - assert 'cfg_dget' not in __builtin__.__dict__ - __builtin__.__dict__['cfg_dget'] = self._cfg.dget - - def domain_add(self, domainname, transport=None): - """Wrapper around Domain's set_quotalimit, set_transport and save.""" - dom = self._get_domain(domainname) - if transport is None: - dom.set_transport(Transport(self._dbh, - transport=self._cfg.dget('domain.transport'))) - else: - dom.set_transport(Transport(self._dbh, transport=transport)) - dom.set_quotalimit(QuotaLimit(self._dbh, - bytes=long(self._cfg.dget('domain.quota_bytes')), - messages=self._cfg.dget('domain.quota_messages'))) - dom.set_serviceset(ServiceSet(self._dbh, - imap=self._cfg.dget('domain.imap'), - pop3=self._cfg.dget('domain.pop3'), - sieve=self._cfg.dget('domain.sieve'), - smtp=self._cfg.dget('domain.smtp'))) - dom.set_directory(self._cfg.dget('misc.base_directory')) - dom.save() - self._make_domain_dir(dom) - - def domain_quotalimit(self, domainname, bytes_, messages=0, force=None): - """Wrapper around Domain.update_quotalimit().""" - if not all(isinstance(i, (int, long)) for i in (bytes_, messages)): - raise TypeError("'bytes_' and 'messages' have to be " - "integers or longs.") - if force is not None and force != 'force': - raise DomainError(_(u"Invalid argument: '%s'") % force, - INVALID_ARGUMENT) - dom = self._get_domain(domainname) - quotalimit = QuotaLimit(self._dbh, bytes=bytes_, messages=messages) - if force is None: - dom.update_quotalimit(quotalimit) - else: - dom.update_quotalimit(quotalimit, force=True) - - def domain_services(self, domainname, force=None, *services): - """Wrapper around Domain.update_serviceset().""" - kwargs = dict.fromkeys(SERVICES, False) - if force is not None and force != 'force': - raise DomainError(_(u"Invalid argument: '%s'") % force, - INVALID_ARGUMENT) - for service in set(services): - if service not in SERVICES: - raise DomainError(_(u"Unknown service: '%s'") % service, - UNKNOWN_SERVICE) - kwargs[service] = True - - dom = self._get_domain(domainname) - serviceset = ServiceSet(self._dbh, **kwargs) - dom.update_serviceset(serviceset, (True, False)[not force]) - - def domain_transport(self, domainname, transport, force=None): - """Wrapper around Domain.update_transport()""" - if force is not None and force != 'force': - raise DomainError(_(u"Invalid argument: '%s'") % force, - INVALID_ARGUMENT) - dom = self._get_domain(domainname) - trsp = Transport(self._dbh, transport=transport) - if force is None: - dom.update_transport(trsp) - else: - dom.update_transport(trsp, force=True) - - def domain_note(self, domainname, note): - """Wrapper around Domain.update_note()""" - dom = self._get_domain(domainname) - dom.update_note(note) - - def domain_delete(self, domainname, force=False): - """Wrapper around Domain.delete()""" - if not isinstance(force, bool): - raise TypeError('force must be a bool') - dom = self._get_domain(domainname) - gid = dom.gid - domdir = dom.directory - if self._cfg.dget('domain.force_deletion') or force: - dom.delete(True) - else: - dom.delete(False) - if self._cfg.dget('domain.delete_directory'): - self._delete_domain_dir(domdir, gid) - - def domain_info(self, domainname, details=None): - """Wrapper around Domain.get_info(), Domain.get_accounts(), - Domain.get_aliase_names(), Domain.get_aliases() and - Domain.get_relocated.""" - if details not in [None, 'accounts', 'aliasdomains', 'aliases', 'full', - 'relocated', 'catchall']: - raise VMMError(_(u"Invalid argument: '%s'") % details, - INVALID_ARGUMENT) - dom = self._get_domain(domainname) - dominfo = dom.get_info() - if dominfo['domain name'].startswith('xn--') or \ - dominfo['domain name'].count('.xn--'): - dominfo['domain name'] += ' (%s)' % \ - dominfo['domain name'].decode('idna') - if details is None: - return dominfo - elif details == 'accounts': - return (dominfo, dom.get_accounts()) - elif details == 'aliasdomains': - return (dominfo, dom.get_aliase_names()) - elif details == 'aliases': - return (dominfo, dom.get_aliases()) - elif details == 'relocated': - return(dominfo, dom.get_relocated()) - elif details == 'catchall': - return(dominfo, dom.get_catchall()) - else: - return (dominfo, dom.get_aliase_names(), dom.get_accounts(), - dom.get_aliases(), dom.get_relocated(), dom.get_catchall()) - - def aliasdomain_add(self, aliasname, domainname): - """Adds an alias domain to the domain. - - Arguments: - - `aliasname` : basestring - The name of the alias domain - `domainname` : basestring - The name of the target domain - """ - dom = self._get_domain(domainname) - alias_dom = AliasDomain(self._dbh, aliasname) - alias_dom.set_destination(dom) - alias_dom.save() - - def aliasdomain_info(self, aliasname): - """Returns a dict (keys: "alias" and "domain") with the names of - the alias domain and its primary domain.""" - self._db_connect() - alias_dom = AliasDomain(self._dbh, aliasname) - return alias_dom.info() - - def aliasdomain_switch(self, aliasname, domainname): - """Modifies the target domain of an existing alias domain. - - Arguments: - - `aliasname` : basestring - The name of the alias domain - `domainname` : basestring - The name of the new target domain - """ - dom = self._get_domain(domainname) - alias_dom = AliasDomain(self._dbh, aliasname) - alias_dom.set_destination(dom) - alias_dom.switch() - - def aliasdomain_delete(self, aliasname): - """Deletes the given alias domain. - - Argument: - - `aliasname` : basestring - The name of the alias domain - """ - self._db_connect() - alias_dom = AliasDomain(self._dbh, aliasname) - alias_dom.delete() - - def domain_list(self, pattern=None): - """Wrapper around function search() from module Domain.""" - from VirtualMailManager.domain import search - like = False - if pattern and (pattern.startswith('%') or pattern.endswith('%')): - like = True - if not re.match(RE_DOMAIN_SEARCH, pattern.strip('%')): - raise VMMError(_(u"The pattern '%s' contains invalid " - u"characters.") % pattern, DOMAIN_INVALID) - self._db_connect() - return search(self._dbh, pattern=pattern, like=like) - - def address_list(self, typelimit, pattern=None): - """TODO""" - llike = dlike = False - lpattern = dpattern = None - if pattern: - parts = pattern.split('@', 2) - if len(parts) == 2: - # The pattern includes '@', so let's treat the - # parts separately to allow for pattern search like %@domain.% - lpattern = parts[0] - llike = lpattern.startswith('%') or lpattern.endswith('%') - dpattern = parts[1] - dlike = dpattern.startswith('%') or dpattern.endswith('%') - - if llike: - checkp = lpattern.strip('%') - else: - checkp = lpattern - if len(checkp) > 0 and re.search(RE_LOCALPART, checkp): - raise VMMError(_(u"The pattern '%s' contains invalid " - u"characters.") % pattern, - LOCALPART_INVALID) - else: - # else just match on domains - # (or should that be local part, I don't know…) - dpattern = parts[0] - dlike = dpattern.startswith('%') or dpattern.endswith('%') - - if dlike: - checkp = dpattern.strip('%') - else: - checkp = dpattern - if len(checkp) > 0 and not re.match(RE_DOMAIN_SEARCH, checkp): - raise VMMError(_(u"The pattern '%s' contains invalid " - u"characters.") % pattern, DOMAIN_INVALID) - self._db_connect() - from VirtualMailManager.common import search_addresses - return search_addresses(self._dbh, typelimit=typelimit, - lpattern=lpattern, llike=llike, - dpattern=dpattern, dlike=dlike) - - def user_add(self, emailaddress, password): - """Wrapper around Account.set_password() and Account.save().""" - acc = self._get_account(emailaddress) - if acc: - raise VMMError(_(u"The account '%s' already exists.") % - acc.address, ACCOUNT_EXISTS) - self._is_other_address(acc.address, TYPE_ACCOUNT) - acc.set_password(password) - acc.save() - self._make_account_dirs(acc) - - def alias_add(self, aliasaddress, *targetaddresses): - """Creates a new `Alias` entry for the given *aliasaddress* with - the given *targetaddresses*.""" - alias = self._get_alias(aliasaddress) - if not alias: - self._is_other_address(alias.address, TYPE_ALIAS) - destinations = [DestinationEmailAddress(addr, self._dbh) - for addr in targetaddresses] - warnings = [] - destinations = alias.add_destinations(destinations, warnings) - if warnings: - self._warnings.append(_('Ignored destination addresses:')) - self._warnings.extend((' * %s' % w for w in warnings)) - for destination in destinations: - if destination.gid and \ - not self._chk_other_address_types(destination, TYPE_RELOCATED): - self._warnings.append(_(u"The destination account/alias '%s' " - u"does not exist.") % destination) - - def user_delete(self, emailaddress, force=False): - """Wrapper around Account.delete(...)""" - if not isinstance(force, bool): - raise TypeError('force must be a bool') - acc = self._get_account(emailaddress) - if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % - acc.address, NO_SUCH_ACCOUNT) - uid = acc.uid - gid = acc.gid - dom_dir = acc.domain.directory - acc_dir = acc.home - acc.delete(force) - if self._cfg.dget('account.delete_directory'): - try: - self._delete_home(dom_dir, uid, gid) - except VMMError, err: - if err.code in (FOUND_DOTS_IN_PATH, MAILDIR_PERM_MISMATCH, - NO_SUCH_DIRECTORY): - warning = _(u"""\ -The account has been successfully deleted from the database. - But an error occurred while deleting the following directory: - '%(directory)s' - Reason: %(reason)s""") % {'directory': acc_dir, 'reason': err.msg} - self._warnings.append(warning) - else: - raise - - def alias_info(self, aliasaddress): - """Returns an iterator object for all destinations (`EmailAddress` - instances) for the `Alias` with the given *aliasaddress*.""" - alias = self._get_alias(aliasaddress) - if alias: - return alias.get_destinations() - if not self._is_other_address(alias.address, TYPE_ALIAS): - raise VMMError(_(u"The alias '%s' does not exist.") % - alias.address, NO_SUCH_ALIAS) - - def alias_delete(self, aliasaddress, targetaddresses=None): - """Deletes the `Alias` *aliasaddress* with all its destinations from - the database. If *targetaddresses* is not ``None``, only the given - destinations will be removed from the alias.""" - alias = self._get_alias(aliasaddress) - error = None - if targetaddresses is None: - alias.delete() - else: - destinations = [DestinationEmailAddress(addr, self._dbh) - for addr in targetaddresses] - warnings = [] - try: - alias.del_destinations(destinations, warnings) - except VMMError, err: - error = err - if warnings: - self._warnings.append(_('Ignored destination addresses:')) - self._warnings.extend((' * %s' % w for w in warnings)) - if error: - raise error - - def catchall_add(self, domain, *targetaddresses): - """Creates a new `CatchallAlias` entry for the given *domain* with - the given *targetaddresses*.""" - catchall = self._get_catchall(domain) - destinations = [DestinationEmailAddress(addr, self._dbh) - for addr in targetaddresses] - warnings = [] - destinations = catchall.add_destinations(destinations, warnings) - if warnings: - self._warnings.append(_('Ignored destination addresses:')) - self._warnings.extend((' * %s' % w for w in warnings)) - for destination in destinations: - if destination.gid and \ - not self._chk_other_address_types(destination, TYPE_RELOCATED): - self._warnings.append(_(u"The destination account/alias '%s' " - u"does not exist.") % destination) - - def catchall_info(self, domain): - """Returns an iterator object for all destinations (`EmailAddress` - instances) for the `CatchallAlias` with the given *domain*.""" - return self._get_catchall(domain).get_destinations() - - def catchall_delete(self, domain, targetaddresses=None): - """Deletes the `CatchallAlias` for domain *domain* with all its - destinations from the database. If *targetaddresses* is not - ``None``, only those destinations will be removed from the alias.""" - catchall = self._get_catchall(domain) - error = None - if targetaddresses is None: - catchall.delete() - else: - destinations = [DestinationEmailAddress(addr, self._dbh) - for addr in targetaddresses] - warnings = [] - try: - catchall.del_destinations(destinations, warnings) - except VMMError, err: - error = err - if warnings: - self._warnings.append(_('Ignored destination addresses:')) - self._warnings.extend((' * %s' % w for w in warnings)) - if error: - raise error - - def user_info(self, emailaddress, details=None): - """Wrapper around Account.get_info(...)""" - if details not in (None, 'du', 'aliases', 'full'): - raise VMMError(_(u"Invalid argument: '%s'") % details, - INVALID_ARGUMENT) - acc = self._get_account(emailaddress) - if not acc: - if not self._is_other_address(acc.address, TYPE_ACCOUNT): - raise VMMError(_(u"The account '%s' does not exist.") % - acc.address, NO_SUCH_ACCOUNT) - info = acc.get_info() - if self._cfg.dget('account.disk_usage') or details in ('du', 'full'): - path = os.path.join(acc.home, acc.mail_location.directory) - info['disk usage'] = self._get_disk_usage(path) - if details in (None, 'du'): - return info - if details in ('aliases', 'full'): - return (info, acc.get_aliases()) - return info - - def user_by_uid(self, uid): - """Search for an Account by its *uid*. - Returns a dict (address, uid and gid) if a user could be found.""" - from VirtualMailManager.account import get_account_by_uid - self._db_connect() - return get_account_by_uid(uid, self._dbh) - - def user_password(self, emailaddress, password): - """Wrapper for Account.modify('password' ...).""" - if not isinstance(password, basestring) or not password: - raise VMMError(_(u"Could not accept password: '%s'") % password, - INVALID_ARGUMENT) - acc = self._get_account(emailaddress) - if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % - acc.address, NO_SUCH_ACCOUNT) - acc.modify('password', password) - - def user_name(self, emailaddress, name): - """Wrapper for Account.modify('name', ...).""" - acc = self._get_account(emailaddress) - if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % - acc.address, NO_SUCH_ACCOUNT) - acc.modify('name', name) - - def user_note(self, emailaddress, note): - """Wrapper for Account.modify('note', ...).""" - acc = self._get_account(emailaddress) - if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % - acc.address, NO_SUCH_ACCOUNT) - acc.modify('note', note) - - def user_quotalimit(self, emailaddress, bytes_, messages=0): - """Wrapper for Account.update_quotalimit(QuotaLimit).""" - acc = self._get_account(emailaddress) - if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % - acc.address, NO_SUCH_ACCOUNT) - if bytes_ == 'domain': - quotalimit = None - else: - if not all(isinstance(i, (int, long)) for i in (bytes_, messages)): - raise TypeError("'bytes_' and 'messages' have to be " - "integers or longs.") - quotalimit = QuotaLimit(self._dbh, bytes=bytes_, - messages=messages) - acc.update_quotalimit(quotalimit) - - def user_transport(self, emailaddress, transport): - """Wrapper for Account.update_transport(Transport).""" - if not isinstance(transport, basestring) or not transport: - raise VMMError(_(u"Could not accept transport: '%s'") % transport, - INVALID_ARGUMENT) - acc = self._get_account(emailaddress) - if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % - acc.address, NO_SUCH_ACCOUNT) - if transport == 'domain': - transport = None - else: - transport = Transport(self._dbh, transport=transport) - acc.update_transport(transport) - - def user_services(self, emailaddress, *services): - """Wrapper around Account.update_serviceset().""" - acc = self._get_account(emailaddress) - if not acc: - raise VMMError(_(u"The account '%s' does not exist.") % - acc.address, NO_SUCH_ACCOUNT) - if len(services) == 1 and services[0] == 'domain': - serviceset = None - else: - kwargs = dict.fromkeys(SERVICES, False) - for service in set(services): - if service not in SERVICES: - raise VMMError(_(u"Unknown service: '%s'") % service, - UNKNOWN_SERVICE) - kwargs[service] = True - serviceset = ServiceSet(self._dbh, **kwargs) - acc.update_serviceset(serviceset) - - def relocated_add(self, emailaddress, targetaddress): - """Creates a new `Relocated` entry in the database. If there is - already a relocated user with the given *emailaddress*, only the - *targetaddress* for the relocated user will be updated.""" - relocated = self._get_relocated(emailaddress) - if not relocated: - self._is_other_address(relocated.address, TYPE_RELOCATED) - destination = DestinationEmailAddress(targetaddress, self._dbh) - relocated.set_destination(destination) - if destination.gid and \ - not self._chk_other_address_types(destination, TYPE_RELOCATED): - self._warnings.append(_(u"The destination account/alias '%s' " - u"does not exist.") % destination) - - def relocated_info(self, emailaddress): - """Returns the target address of the relocated user with the given - *emailaddress*.""" - relocated = self._get_relocated(emailaddress) - if relocated: - return relocated.get_info() - if not self._is_other_address(relocated.address, TYPE_RELOCATED): - raise VMMError(_(u"The relocated user '%s' does not exist.") % - relocated.address, NO_SUCH_RELOCATED) - - def relocated_delete(self, emailaddress): - """Deletes the relocated user with the given *emailaddress* from - the database.""" - relocated = self._get_relocated(emailaddress) - relocated.delete() - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/mailbox.py --- a/VirtualMailManager/mailbox.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,294 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2010 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.mailbox - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - VirtualMailManager's mailbox classes for the Maildir, single dbox - (sdbox) and multi dbox (mdbox) mailbox formats. -""" - -import os -import re -from binascii import a2b_base64, b2a_base64 -from subprocess import Popen, PIPE - -from VirtualMailManager.account import Account -from VirtualMailManager.common import lisdir -from VirtualMailManager.errors import VMMError -from VirtualMailManager.constants import VMM_ERROR - - -__all__ = ('new', 'Maildir', 'SingleDbox', 'MultiDbox', - 'utf8_to_mutf7', 'mutf7_to_utf8') - -_ = lambda msg: msg -cfg_dget = lambda option: None - - -def _mbase64_encode(inp, dest): - if inp: - mb64 = b2a_base64(''.join(inp).encode('utf-16be')) - dest.append('&%s-' % mb64.rstrip('\n=').replace('/', ',')) - del inp[:] - - -def _mbase64_to_unicode(mb64): - return unicode(a2b_base64(mb64.replace(',', '/') + '==='), 'utf-16be') - - -def utf8_to_mutf7(src): - """ - Converts the international mailbox name `src` into a modified - version version of the UTF-7 encoding. - """ - ret = [] - tmp = [] - for c in src: - ordc = ord(c) - if 0x20 <= ordc <= 0x25 or 0x27 <= ordc <= 0x7E: - _mbase64_encode(tmp, ret) - ret.append(c) - elif ordc == 0x26: - _mbase64_encode(tmp, ret) - ret.append('&-') - else: - tmp.append(c) - _mbase64_encode(tmp, ret) - return ''.join(ret) - - -def mutf7_to_utf8(src): - """ - Converts the mailbox name `src` from modified UTF-7 encoding to UTF-8. - """ - ret = [] - tmp = [] - for c in src: - if c == '&' and not tmp: - tmp.append(c) - elif c == '-' and tmp: - if len(tmp) is 1: - ret.append('&') - else: - ret.append(_mbase64_to_unicode(''.join(tmp[1:]))) - tmp = [] - elif tmp: - tmp.append(c) - else: - ret.append(c) - if tmp: - ret.append(_mbase64_to_unicode(''.join(tmp[1:]))) - return ''.join(ret) - - -class Mailbox(object): - """Base class of all mailbox classes.""" - __slots__ = ('_boxes', '_root', '_sep', '_user') - FILE_MODE = 0600 - _ctrl_chr_re = re.compile('[\x00-\x1F\x7F-\x9F]') - _box_name_re = re.compile('^[\x20-\x25\x27-\x7E]+$') - - def __init__(self, account): - """ - Creates a new mailbox instance. - Use one of the `Maildir`, `SingleDbox` or `MultiDbox` classes. - """ - assert isinstance(account, Account) and lisdir(account.home) - self._user = account - self._boxes = [] - self._root = self._user.mail_location.directory - self._sep = '/' - os.chdir(self._user.home) - - def _add_boxes(self, mailboxes, subscribe): - """Create all mailboxes from the `mailboxes` list. - If `subscribe` is *True*, the mailboxes will be listed in the - subscriptions file.""" - raise NotImplementedError - - def _validate_box_name(self, name, good, bad): - """ - Validates the mailboxes name `name`. When the name is valid, it - will be added to the `good` set. Invalid mailbox names will be - appended to the `bad` list. - """ - name = name.strip() - if not name: - return - if self.__class__._ctrl_chr_re.search(name): # no control chars - bad.append(name) - return - if name[0] in (self._sep, '~'): - bad.append(name) - return - if self._sep == '/': - if '//' in name or '/./' in name or '/../' in name or \ - name.startswith('../'): - bad.append(name) - return - elif '/' in name or '..' in name: - bad.append(name) - return - if not self.__class__._box_name_re.match(name): - tmp = utf8_to_mutf7(name) - if name == mutf7_to_utf8(tmp): - if self._user.mail_location.mbformat == 'maildir': - good.add(tmp) - else: - good.add(name) - return - else: - bad.append(name) - return - good.add(name) - - def add_boxes(self, mailboxes, subscribe): - """ - Create all mailboxes from the `mailboxes` list in the user's - mail directory. When `subscribe` is ``True`` all created mailboxes - will be listed in the subscriptions file. - Returns a list of invalid mailbox names, if any. - """ - assert isinstance(mailboxes, list) and isinstance(subscribe, bool) - good = set() - bad = [] - for box in mailboxes: - if self._sep == '/': - box = box.replace('.', self._sep) - self._validate_box_name(box, good, bad) - self._add_boxes(good, subscribe) - return bad - - def create(self): - """Create the INBOX in the user's mail directory.""" - raise NotImplementedError - - -class Maildir(Mailbox): - """Class for Maildir++ mailboxes.""" - - __slots__ = ('_subdirs') - - def __init__(self, account): - """ - Create a new Maildir++ instance. - Call the instance's create() method, in order to create the INBOX. - For additional mailboxes use the add_boxes() method. - """ - super(self.__class__, self).__init__(account) - self._sep = '.' - self._subdirs = ('cur', 'new', 'tmp') - - def _create_maildirfolder_file(self, path): - """Mark the Maildir++ folder as Maildir folder.""" - maildirfolder_file = os.path.join(self._sep + path, 'maildirfolder') - os.close(os.open(maildirfolder_file, os.O_CREAT | os.O_WRONLY, - self.__class__.FILE_MODE)) - os.chown(maildirfolder_file, self._user.uid, self._user.gid) - - def _make_maildir(self, path): - """ - Create Maildir++ folders with the cur, new and tmp subdirectories. - """ - mode = cfg_dget('account.directory_mode') - uid = self._user.uid - gid = self._user.gid - os.mkdir(path, mode) - os.chown(path, uid, gid) - for subdir in self._subdirs: - dir_ = os.path.join(path, subdir) - os.mkdir(dir_, mode) - os.chown(dir_, uid, gid) - - def _subscribe_boxes(self): - """Writes all created mailboxes to the subscriptions file.""" - if not self._boxes: - return - subscriptions = open('subscriptions', 'w') - subscriptions.write('\n'.join(self._boxes)) - subscriptions.write('\n') - subscriptions.flush() - subscriptions.close() - os.chown('subscriptions', self._user.uid, self._user.gid) - os.chmod('subscriptions', self.__class__.FILE_MODE) - del self._boxes[:] - - def _add_boxes(self, mailboxes, subscribe): - for mailbox in mailboxes: - self._make_maildir(self._sep + mailbox) - self._create_maildirfolder_file(mailbox) - self._boxes.append(mailbox) - if subscribe: - self._subscribe_boxes() - - def create(self): - """Creates a Maildir++ INBOX.""" - self._make_maildir(self._root) - os.chdir(self._root) - - -class SingleDbox(Mailbox): - """ - Class for (single) dbox mailboxes. - See http://wiki.dovecot.org/MailboxFormat/dbox for details. - """ - - __slots__ = () - - def __init__(self, account): - """ - Create a new dbox instance. - Call the instance's create() method, in order to create the INBOX. - For additional mailboxes use the add_boxes() method. - """ - assert cfg_dget('misc.dovecot_version') >= \ - account.mail_location.dovecot_version - super(SingleDbox, self).__init__(account) - - def _doveadm_create(self, mailboxes, subscribe): - """Wrap around Dovecot's doveadm""" - cmd_args = [cfg_dget('bin.dovecotpw'), 'mailbox', 'create', '-u', - str(self._user.address)] - if subscribe: - cmd_args.append('-s') - cmd_args.extend(mailboxes) - process = Popen(cmd_args, stderr=PIPE) - stderr = process.communicate()[1] - if process.returncode: - e_msg = _(u'Failed to create mailboxes: %r\n') % mailboxes - raise VMMError(e_msg + stderr.strip(), VMM_ERROR) - - def create(self): - """Create a dbox INBOX""" - os.mkdir(self._root, cfg_dget('account.directory_mode')) - os.chown(self._root, self._user.uid, self._user.gid) - self._doveadm_create(('INBOX',), False) - os.chdir(self._root) - - def _add_boxes(self, mailboxes, subscribe): - self._doveadm_create(mailboxes, subscribe) - - -class MultiDbox(SingleDbox): - """ - Class for multi dbox mailboxes. - See http://wiki.dovecot.org/MailboxFormat/dbox#Multi-dbox for details. - """ - - __slots__ = () - - -def new(account): - """Create a new Mailbox instance for the given Account.""" - mbfmt = account.mail_location.mbformat - if mbfmt == 'maildir': - return Maildir(account) - elif mbfmt == 'mdbox': - return MultiDbox(account) - elif mbfmt == 'sdbox': - return SingleDbox(account) - raise ValueError('unsupported mailbox format: %r' % mbfmt) - -del _, cfg_dget diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/maillocation.py --- a/VirtualMailManager/maillocation.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2008 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.maillocation - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's maillocation module to handle Dovecot's - mail_location setting for accounts. - -""" - -from VirtualMailManager.constants import MAILLOCATION_INIT -from VirtualMailManager.errors import MailLocationError as MLErr -from VirtualMailManager.pycompat import all - - -__all__ = ('MailLocation', 'known_format') - -_ = lambda msg: msg -_format_info = { - 'maildir': dict(dovecot_version=0x10000f00, postfix=True), - 'mdbox': dict(dovecot_version=0x20000b05, postfix=False), - 'sdbox': dict(dovecot_version=0x20000c03, postfix=False), -} - - -class MailLocation(object): - """Class to handle mail_location relevant information.""" - __slots__ = ('_directory', '_mbfmt', '_mid', '_dbh') - _kwargs = ('mid', 'mbfmt', 'directory') - - def __init__(self, dbh, **kwargs): - """Creates a new MailLocation instance. - - Either the mid keyword or the mbfmt and directory keywords must be - specified. - - Arguments: - - `dbh` : pyPgSQL.PgSQL.Connection - A database connection for the database access. - - Keyword arguments: - - `mid` : int - the id of a mail_location - `mbfmt` : str - the mailbox format of the mail_location. One out of: ``maildir``, - ``sdbox`` and ``mdbox``. - `directory` : str - name of the mailbox root directory. - """ - self._dbh = dbh - self._directory = None - self._mbfmt = None - self._mid = 0 - - for key in kwargs.iterkeys(): - if key not in self.__class__._kwargs: - raise ValueError('unrecognized keyword: %r' % key) - mid = kwargs.get('mid') - if mid: - assert isinstance(mid, (int, long)) - self._load_by_mid(mid) - else: - args = kwargs.get('mbfmt'), kwargs.get('directory') - assert all(isinstance(arg, basestring) for arg in args) - if args[0].lower() not in _format_info: - raise MLErr(_(u"Unsupported mailbox format: '%s'") % args[0], - MAILLOCATION_INIT) - directory = args[1].strip() - if not directory: - raise MLErr(_(u"Empty directory name"), MAILLOCATION_INIT) - if len(directory) > 20: - raise MLErr(_(u"Directory name is too long: '%s'") % directory, - MAILLOCATION_INIT) - self._load_by_names(args[0].lower(), directory) - - def __str__(self): - return u'%s:~/%s' % (self._mbfmt, self._directory) - - @property - def directory(self): - """The mail_location's directory name.""" - return self._directory - - @property - def dovecot_version(self): - """The required Dovecot version for this mailbox format.""" - return _format_info[self._mbfmt]['dovecot_version'] - - @property - def postfix(self): - """`True` if Postfix supports this mailbox format, else `False`.""" - return _format_info[self._mbfmt]['postfix'] - - @property - def mbformat(self): - """The mail_location's mailbox format.""" - return self._mbfmt - - @property - def mail_location(self): - """The mail_location, e.g. ``maildir:~/Maildir``""" - return self.__str__() - - @property - def mid(self): - """The mail_location's unique ID.""" - return self._mid - - def _load_by_mid(self, mid): - """Load mail_location relevant information by *mid*""" - dbc = self._dbh.cursor() - dbc.execute('SELECT format, directory FROM mailboxformat, ' - 'maillocation WHERE mid = %u AND ' - 'maillocation.fid = mailboxformat.fid' % mid) - result = dbc.fetchone() - dbc.close() - if not result: - raise ValueError('Unknown mail_location id specified: %r' % mid) - self._mid = mid - self._mbfmt, self._directory = result - - def _load_by_names(self, mbfmt, directory): - """Try to load mail_location relevant information by *mbfmt* and - *directory* name. If it fails goto _save().""" - dbc = self._dbh.cursor() - dbc.execute("SELECT mid FROM maillocation WHERE fid = (SELECT fid " - "FROM mailboxformat WHERE format = %s) AND directory = %s", - (mbfmt, directory)) - result = dbc.fetchone() - dbc.close() - if not result: - self._save(mbfmt, directory) - else: - self._mid = result[0] - self._mbfmt = mbfmt - self._directory = directory - - def _save(self, mbfmt, directory): - """Save a new mail_location in the database.""" - dbc = self._dbh.cursor() - dbc.execute("SELECT nextval('maillocation_id')") - mid = dbc.fetchone()[0] - dbc.execute("INSERT INTO maillocation (fid, mid, directory) VALUES (" - "(SELECT fid FROM mailboxformat WHERE format = %s), %s, " - "%s)", (mbfmt, mid, directory)) - self._dbh.commit() - dbc.close() - self._mid = mid - self._mbfmt = mbfmt - self._directory = directory - - -def known_format(mbfmt): - """Checks if the mailbox format *mbfmt* is known, returns bool.""" - return mbfmt.lower() in _format_info - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/network.py --- a/VirtualMailManager/network.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2011 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.network - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Network/IP address related class and function -""" - -import socket - - -class NetInfo(object): - """Simple class for CIDR network addresses an IP addresses.""" - __slots__ = ('_addr', '_prefix', '_bits_max', '_family', '_nw_addr') - - def __init__(self, nw_address): - """Creates a new `NetInfo` instance. - - Argument: - - `nw_address` : basestring - string representation of an IPv4/IPv6 address or network address. - E.g. 192.0.2.13, 192.0.2.0/24, 2001:db8::/32 or ::1 - When the address has no netmask the prefix length will be set to - 32 for IPv4 addresses and 128 for IPv6 addresses. - """ - self._addr = None - self._prefix = 0 - self._bits_max = 0 - self._family = 0 - self._nw_addr = nw_address - self._parse_net_range() - - def __hash__(self): - return hash((self._addr, self._family, self._prefix)) - - def __repr__(self): - return "NetInfo('%s')" % self._nw_addr - - def _parse_net_range(self): - """Parse the network range of `self._nw_addr and assign values - to the class attributes. - `""" - sep = '/' - if self._nw_addr.count(sep): - ip_address, sep, self._prefix = self._nw_addr.partition(sep) - self._family, self._addr = get_ip_addr_info(ip_address) - else: - self._family, self._addr = get_ip_addr_info(self._nw_addr) - self._bits_max = (128, 32)[self._family is socket.AF_INET] - if self._prefix is 0: - self._prefix = self._bits_max - else: - try: - self._prefix = int(self._prefix) - except ValueError: - raise ValueError('Invalid prefix length: %r' % self._prefix) - if self._prefix > self._bits_max or self._prefix < 0: - raise ValueError('Invalid prefix length: %r' % self._prefix) - - @property - def family(self): - """Address family: `socket.AF_INET` or `socket.AF_INET6`""" - return self._family - - def address_in_net(self, ip_address): - """Checks if the `ip_address` belongs to the same subnet.""" - family, address = get_ip_addr_info(ip_address) - if family != self._family: - return False - return address >> self._bits_max - self._prefix == \ - self._addr >> self._bits_max - self._prefix - - -def get_ip_addr_info(ip_address): - """Checks if the string `ip_address` is a valid IPv4 or IPv6 address. - - When the `ip_address` could be validated successfully a tuple - `(address_family, address_as_long)` will be returned. The - `address_family`will be either `socket.AF_INET` or `socket.AF_INET6`. - """ - if not isinstance(ip_address, basestring) or not ip_address: - raise TypeError('ip_address must be a non empty string.') - if not ip_address.count(':'): - family = socket.AF_INET - try: - address = socket.inet_aton(ip_address) - except socket.error: - raise ValueError('Not a valid IPv4 address: %r' % ip_address) - elif not socket.has_ipv6: - raise ValueError('Unsupported IP address (IPv6): %r' % ip_address) - else: - family = socket.AF_INET6 - try: - address = socket.inet_pton(family, ip_address) - except socket.error: - raise ValueError('Not a valid IPv6 address: %r' % ip_address) - return (family, long(address.encode('hex'), 16)) diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/password.py --- a/VirtualMailManager/password.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,460 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2010 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.password - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - VirtualMailManager's password module to generate password hashes from - passwords or random passwords. This module provides following - functions: - - hashed_password = pwhash(password[, scheme][, user]) - random_password = randompw() - scheme, encoding = verify_scheme(scheme) - schemes, encodings = list_schemes() -""" - -from crypt import crypt -from random import SystemRandom -from subprocess import Popen, PIPE - -try: - import hashlib -except ImportError: - from VirtualMailManager.pycompat import hashlib - -from VirtualMailManager import ENCODING -from VirtualMailManager.emailaddress import EmailAddress -from VirtualMailManager.common import get_unicode, version_str -from VirtualMailManager.constants import VMM_ERROR -from VirtualMailManager.errors import VMMError - -COMPAT = hasattr(hashlib, 'compat') -SALTCHARS = './0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' -PASSWDCHARS = '._-+#*23456789abcdefghikmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ' -DEFAULT_B64 = (None, 'B64', 'BASE64') -DEFAULT_HEX = (None, 'HEX') -CRYPT_ID_MD5 = 1 -CRYPT_ID_BLF = '2a' -CRYPT_ID_SHA256 = 5 -CRYPT_ID_SHA512 = 6 -CRYPT_SALT_LEN = 2 -CRYPT_BLF_ROUNDS_MIN = 4 -CRYPT_BLF_ROUNDS_MAX = 31 -CRYPT_BLF_SALT_LEN = 22 -CRYPT_MD5_SALT_LEN = 8 -CRYPT_SHA2_ROUNDS_DEFAULT = 5000 -CRYPT_SHA2_ROUNDS_MIN = 1000 -CRYPT_SHA2_ROUNDS_MAX = 999999999 -CRYPT_SHA2_SALT_LEN = 16 -SALTED_ALGO_SALT_LEN = 4 - - -_ = lambda msg: msg -cfg_dget = lambda option: None -_sys_rand = SystemRandom() -_choice = _sys_rand.choice -_get_salt = lambda s_len: ''.join(_choice(SALTCHARS) for x in xrange(s_len)) - - -def _dovecotpw(password, scheme, encoding): - """Communicates with dovecotpw (Dovecot 2.0: `doveadm pw`) and returns - the hashed password: {scheme[.encoding]}hash - """ - if encoding: - scheme = '.'.join((scheme, encoding)) - cmd_args = [cfg_dget('bin.dovecotpw'), '-s', scheme, '-p', - get_unicode(password)] - if cfg_dget('misc.dovecot_version') >= 0x20000a01: - cmd_args.insert(1, 'pw') - process = Popen(cmd_args, stdout=PIPE, stderr=PIPE) - stdout, stderr = process.communicate() - if process.returncode: - raise VMMError(stderr.strip(), VMM_ERROR) - hashed = stdout.strip() - if not hashed.startswith('{%s}' % scheme): - raise VMMError('Unexpected result from %s: %s' % - (cfg_dget('bin.dovecotpw'), hashed), VMM_ERROR) - return hashed - - -def _md4_new(): - """Returns an new MD4-hash object if supported by the hashlib or - provided by PyCrypto - other `None`. - """ - try: - return hashlib.new('md4') - except ValueError, err: - if str(err) == 'unsupported hash type': - if not COMPAT: - try: - from Crypto.Hash import MD4 - return MD4.new() - except ImportError: - return None - else: - raise - - -def _sha256_new(data=''): - """Returns a new sha256 object from the hashlib. - - Returns `None` if the PyCrypto in pycompat.hashlib is too old.""" - if not COMPAT: - return hashlib.sha256(data) - try: - return hashlib.new('sha256', data) - except ValueError, err: - if str(err) == 'unsupported hash type': - return None - else: - raise - - -def _format_digest(digest, scheme, encoding): - """Formats the arguments to a string: {scheme[.encoding]}digest.""" - if not encoding: - return '{%s}%s' % (scheme, digest) - return '{%s.%s}%s' % (scheme, encoding, digest) - - -def _clear_hash(password, scheme, encoding): - """Generates a (encoded) CLEARTEXT/PLAIN 'hash'.""" - if encoding: - if encoding == 'HEX': - password = password.encode('hex') - else: - password = password.encode('base64').replace('\n', '') - return _format_digest(password, scheme, encoding) - return get_unicode('{%s}%s' % (scheme, password)) - - -def _get_crypt_blowfish_salt(): - """Generates a salt for Blowfish crypt.""" - rounds = cfg_dget('misc.crypt_blowfish_rounds') - if rounds < CRYPT_BLF_ROUNDS_MIN: - rounds = CRYPT_BLF_ROUNDS_MIN - elif rounds > CRYPT_BLF_ROUNDS_MAX: - rounds = CRYPT_BLF_ROUNDS_MAX - return '$%s$%02d$%s' % (CRYPT_ID_BLF, rounds, - _get_salt(CRYPT_BLF_SALT_LEN)) - - -def _get_crypt_sha2_salt(crypt_id): - """Generates a salt for crypt using the SHA-256 or SHA-512 encryption - method. - *crypt_id* must be either `5` (SHA-256) or `6` (SHA-512). - """ - assert crypt_id in (CRYPT_ID_SHA256, CRYPT_ID_SHA512), 'invalid crypt ' \ - 'id: %r' % crypt_id - if crypt_id is CRYPT_ID_SHA512: - rounds = cfg_dget('misc.crypt_sha512_rounds') - else: - rounds = cfg_dget('misc.crypt_sha256_rounds') - if rounds < CRYPT_SHA2_ROUNDS_MIN: - rounds = CRYPT_SHA2_ROUNDS_MIN - elif rounds > CRYPT_SHA2_ROUNDS_MAX: - rounds = CRYPT_SHA2_ROUNDS_MAX - if rounds == CRYPT_SHA2_ROUNDS_DEFAULT: - return '$%d$%s' % (crypt_id, _get_salt(CRYPT_SHA2_SALT_LEN)) - return '$%d$rounds=%d$%s' % (crypt_id, rounds, - _get_salt(CRYPT_SHA2_SALT_LEN)) - - -def _crypt_hash(password, scheme, encoding): - """Generates (encoded) CRYPT/MD5/{BLF,MD5,SHA{256,512}}-CRYPT hashes.""" - if scheme == 'CRYPT': - salt = _get_salt(CRYPT_SALT_LEN) - elif scheme == 'BLF-CRYPT': - salt = _get_crypt_blowfish_salt() - elif scheme in ('MD5-CRYPT', 'MD5'): - salt = '$%d$%s' % (CRYPT_ID_MD5, _get_salt(CRYPT_MD5_SALT_LEN)) - elif scheme == 'SHA256-CRYPT': - salt = _get_crypt_sha2_salt(CRYPT_ID_SHA256) - else: - salt = _get_crypt_sha2_salt(CRYPT_ID_SHA512) - encrypted = crypt(password, salt) - if encoding: - if encoding == 'HEX': - encrypted = encrypted.encode('hex') - else: - encrypted = encrypted.encode('base64').replace('\n', '') - if scheme in ('BLF-CRYPT', 'SHA256-CRYPT', 'SHA512-CRYPT') and \ - cfg_dget('misc.dovecot_version') < 0x20000b06: - scheme = 'CRYPT' - return _format_digest(encrypted, scheme, encoding) - - -def _md4_hash(password, scheme, encoding): - """Generates encoded PLAIN-MD4 hashes.""" - md4 = _md4_new() - if md4: - md4.update(password) - if encoding in DEFAULT_HEX: - digest = md4.hexdigest() - else: - digest = md4.digest().encode('base64').rstrip() - return _format_digest(digest, scheme, encoding) - return _dovecotpw(password, scheme, encoding) - - -def _md5_hash(password, scheme, encoding, user=None): - """Generates DIGEST-MD5 aka PLAIN-MD5 and LDAP-MD5 hashes.""" - md5 = hashlib.md5() - if scheme == 'DIGEST-MD5': - # Prior to Dovecot v1.1.12/v1.2.beta2 there was a problem with a - # empty auth_realms setting in dovecot.conf and user@domain.tld - # usernames. So we have to generate different hashes for different - # versions. See also: - # http://dovecot.org/list/dovecot-news/2009-March/000103.html - # http://hg.dovecot.org/dovecot-1.1/rev/2b0043ba89ae - if cfg_dget('misc.dovecot_version') >= 0x1010cf00: - md5.update('%s:%s:' % (user.localpart, user.domainname)) - else: - md5.update('%s::' % user) - md5.update(password) - if (scheme in ('PLAIN-MD5', 'DIGEST-MD5') and encoding in DEFAULT_HEX) or \ - (scheme == 'LDAP-MD5' and encoding == 'HEX'): - digest = md5.hexdigest() - else: - digest = md5.digest().encode('base64').rstrip() - return _format_digest(digest, scheme, encoding) - - -def _ntlm_hash(password, scheme, encoding): - """Generates NTLM hashes.""" - md4 = _md4_new() - if md4: - password = ''.join('%s\x00' % c for c in password) - md4.update(password) - if encoding in DEFAULT_HEX: - digest = md4.hexdigest() - else: - digest = md4.digest().encode('base64').rstrip() - return _format_digest(digest, scheme, encoding) - return _dovecotpw(password, scheme, encoding) - - -def _sha1_hash(password, scheme, encoding): - """Generates SHA1 aka SHA hashes.""" - sha1 = hashlib.sha1(password) - if encoding in DEFAULT_B64: - digest = sha1.digest().encode('base64').rstrip() - else: - digest = sha1.hexdigest() - return _format_digest(digest, scheme, encoding) - - -def _sha256_hash(password, scheme, encoding): - """Generates SHA256 hashes.""" - sha256 = _sha256_new(password) - if sha256: - if encoding in DEFAULT_B64: - digest = sha256.digest().encode('base64').rstrip() - else: - digest = sha256.hexdigest() - return _format_digest(digest, scheme, encoding) - return _dovecotpw(password, scheme, encoding) - - -def _sha512_hash(password, scheme, encoding): - """Generates SHA512 hashes.""" - if not COMPAT: - sha512 = hashlib.sha512(password) - if encoding in DEFAULT_B64: - digest = sha512.digest().encode('base64').replace('\n', '') - else: - digest = sha512.hexdigest() - return _format_digest(digest, scheme, encoding) - return _dovecotpw(password, scheme, encoding) - - -def _smd5_hash(password, scheme, encoding): - """Generates SMD5 (salted PLAIN-MD5) hashes.""" - md5 = hashlib.md5(password) - salt = _get_salt(SALTED_ALGO_SALT_LEN) - md5.update(salt) - if encoding in DEFAULT_B64: - digest = (md5.digest() + salt).encode('base64').rstrip() - else: - digest = md5.hexdigest() + salt.encode('hex') - return _format_digest(digest, scheme, encoding) - - -def _ssha1_hash(password, scheme, encoding): - """Generates SSHA (salted SHA/SHA1) hashes.""" - sha1 = hashlib.sha1(password) - salt = _get_salt(SALTED_ALGO_SALT_LEN) - sha1.update(salt) - if encoding in DEFAULT_B64: - digest = (sha1.digest() + salt).encode('base64').rstrip() - else: - digest = sha1.hexdigest() + salt.encode('hex') - return _format_digest(digest, scheme, encoding) - - -def _ssha256_hash(password, scheme, encoding): - """Generates SSHA256 (salted SHA256) hashes.""" - sha256 = _sha256_new(password) - if sha256: - salt = _get_salt(SALTED_ALGO_SALT_LEN) - sha256.update(salt) - if encoding in DEFAULT_B64: - digest = (sha256.digest() + salt).encode('base64').rstrip() - else: - digest = sha256.hexdigest() + salt.encode('hex') - return _format_digest(digest, scheme, encoding) - return _dovecotpw(password, scheme, encoding) - - -def _ssha512_hash(password, scheme, encoding): - """Generates SSHA512 (salted SHA512) hashes.""" - if not COMPAT: - salt = _get_salt(SALTED_ALGO_SALT_LEN) - sha512 = hashlib.sha512(password + salt) - if encoding in DEFAULT_B64: - digest = (sha512.digest() + salt).encode('base64').replace('\n', - '') - else: - digest = sha512.hexdigest() + salt.encode('hex') - return _format_digest(digest, scheme, encoding) - return _dovecotpw(password, scheme, encoding) - -_scheme_info = { - 'CLEARTEXT': (_clear_hash, 0x10000f00), - 'CRAM-MD5': (_dovecotpw, 0x10000f00), - 'CRYPT': (_crypt_hash, 0x10000f00), - 'DIGEST-MD5': (_md5_hash, 0x10000f00), - 'HMAC-MD5': (_dovecotpw, 0x10000f00), - 'LANMAN': (_dovecotpw, 0x10000f00), - 'LDAP-MD5': (_md5_hash, 0x10000f00), - 'MD5': (_crypt_hash, 0x10000f00), - 'MD5-CRYPT': (_crypt_hash, 0x10000f00), - 'NTLM': (_ntlm_hash, 0x10000f00), - 'OTP': (_dovecotpw, 0x10100a01), - 'PLAIN': (_clear_hash, 0x10000f00), - 'PLAIN-MD4': (_md4_hash, 0x10000f00), - 'PLAIN-MD5': (_md5_hash, 0x10000f00), - 'RPA': (_dovecotpw, 0x10000f00), - 'SCRAM-SHA-1': (_dovecotpw, 0x20200a01), - 'SHA': (_sha1_hash, 0x10000f00), - 'SHA1': (_sha1_hash, 0x10000f00), - 'SHA256': (_sha256_hash, 0x10100a01), - 'SHA512': (_sha512_hash, 0x20000b03), - 'SKEY': (_dovecotpw, 0x10100a01), - 'SMD5': (_smd5_hash, 0x10000f00), - 'SSHA': (_ssha1_hash, 0x10000f00), - 'SSHA256': (_ssha256_hash, 0x10200a04), - 'SSHA512': (_ssha512_hash, 0x20000b03), -} - - -def list_schemes(): - """Returns the tuple (schemes, encodings). - - `schemes` is an iterator for all supported password schemes (depends on - the used Dovecot version and features of the libc). - `encodings` is a tuple with all usable encoding suffixes. The tuple may - be empty. - """ - dcv = cfg_dget('misc.dovecot_version') - schemes = (k for (k, v) in _scheme_info.iteritems() if v[1] <= dcv) - if dcv >= 0x10100a01: - encodings = ('.B64', '.BASE64', '.HEX') - else: - encodings = () - return schemes, encodings - - -def verify_scheme(scheme): - """Checks if the password scheme *scheme* is known and supported by the - configured `misc.dovecot_version`. - - The *scheme* maybe a password scheme's name (e.g.: 'PLAIN') or a scheme - name with a encoding suffix (e.g. 'PLAIN.BASE64'). If the scheme is - known and supported by the used Dovecot version, - a tuple ``(scheme, encoding)`` will be returned. - The `encoding` in the tuple may be `None`. - - Raises a `VMMError` if the password scheme: - * is unknown - * depends on a newer Dovecot version - * has a unknown encoding suffix - """ - assert isinstance(scheme, basestring), 'Not a str/unicode: %r' % scheme - scheme_encoding = scheme.upper().split('.') - scheme = scheme_encoding[0] - if scheme not in _scheme_info: - raise VMMError(_(u"Unsupported password scheme: '%s'") % scheme, - VMM_ERROR) - if cfg_dget('misc.dovecot_version') < _scheme_info[scheme][1]: - raise VMMError(_(u"The password scheme '%(scheme)s' requires Dovecot " - u">= v%(version)s.") % {'scheme': scheme, - 'version': version_str(_scheme_info[scheme][1])}, - VMM_ERROR) - if len(scheme_encoding) > 1: - if cfg_dget('misc.dovecot_version') < 0x10100a01: - raise VMMError(_(u'Encoding suffixes for password schemes require ' - u'Dovecot >= v1.1.alpha1.'), VMM_ERROR) - if scheme_encoding[1] not in ('B64', 'BASE64', 'HEX'): - raise VMMError(_(u"Unsupported password encoding: '%s'") % - scheme_encoding[1], VMM_ERROR) - encoding = scheme_encoding[1] - else: - encoding = None - return scheme, encoding - - -def pwhash(password, scheme=None, user=None): - """Generates a password hash from the plain text *password* string. - - If no *scheme* is given the password scheme from the configuration will - be used for the hash generation. When 'DIGEST-MD5' is used as scheme, - also an EmailAddress instance must be given as *user* argument. - """ - if not isinstance(password, basestring): - raise TypeError('Password is not a string: %r' % password) - if isinstance(password, unicode): - password = password.encode(ENCODING) - password = password.strip() - if not password: - raise ValueError("Could not accept empty password.") - if scheme is None: - scheme = cfg_dget('misc.password_scheme') - scheme, encoding = verify_scheme(scheme) - if scheme == 'DIGEST-MD5': - assert isinstance(user, EmailAddress) - return _md5_hash(password, scheme, encoding, user) - return _scheme_info[scheme][0](password, scheme, encoding) - - -def randompw(): - """Generates a plain text random password. - - The length of the password can be configured in the ``vmm.cfg`` - (account.password_length). - """ - pw_len = cfg_dget('account.password_length') - if pw_len < 8: - pw_len = 8 - return ''.join(_sys_rand.sample(PASSWDCHARS, pw_len)) - - -def _test_crypt_algorithms(): - """Check for Blowfish/SHA-256/SHA-512 support in crypt.crypt().""" - _blowfish = '$2a$04$0123456789abcdefABCDE.N.drYX5yIAL1LkTaaZotW3yI0hQhZru' - _sha256 = '$5$rounds=1000$0123456789abcdef$K/DksR0DT01hGc8g/kt9McEgrbFMKi\ -9qrb1jehe7hn4' - _sha512 = '$6$rounds=1000$0123456789abcdef$ZIAd5WqfyLkpvsVCVUU1GrvqaZTqvh\ -JoouxdSqJO71l9Ld3tVrfOatEjarhghvEYADkq//LpDnTeO90tcbtHR1' - - if crypt('08/15!test~4711', '$2a$04$0123456789abcdefABCDEF$') == _blowfish: - _scheme_info['BLF-CRYPT'] = (_crypt_hash, 0x10000f00) - if crypt('08/15!test~4711', '$5$rounds=1000$0123456789abcdef$') == _sha256: - _scheme_info['SHA256-CRYPT'] = (_crypt_hash, 0x10000f00) - if crypt('08/15!test~4711', '$6$rounds=1000$0123456789abcdef$') == _sha512: - _scheme_info['SHA512-CRYPT'] = (_crypt_hash, 0x10000f00) - -_test_crypt_algorithms() -del _, cfg_dget, _test_crypt_algorithms diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/pycompat/__init__.py --- a/VirtualMailManager/pycompat/__init__.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2010 - 2014, Pascal Volk -# See COPYING for distribution information. - -""" - VirtualMailManager.pycompat - - VirtualMailManager's compatibility stuff for Python 2.4 -""" - -# http://docs.python.org/library/functions.html#all -try: - all = all -except NameError: - def all(iterable): - """Return True if all elements of the *iterable* are true - (or if the iterable is empty). - - """ - for element in iterable: - if not element: - return False - return True - - -# http://docs.python.org/library/functions.html#any -try: - any = any -except NameError: - def any(iterable): - """Return True if any element of the *iterable* is true. If the - iterable is empty, return False. - - """ - for element in iterable: - if element: - return True - return False diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/pycompat/hashlib.py --- a/VirtualMailManager/pycompat/hashlib.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2010 - 2014, Pascal Volk -# See COPYING for distribution information. - -""" - VirtualMailManager.pycompat.hashlib - - VirtualMailManager's minimal hashlib emulation for Python 2.4 - - hashlib.md5(...), hashlib.sha1(...), hashlib.new('md5', ...) and - hashlib.new('sha1', ...) will work always. - - When the PyCrypto module <http://www.pycrypto.org/> could be found in - sys.path hashlib.new('md4', ...) will also work. - - With PyCrypto >= 2.1.0alpha1 hashlib.new('sha256', ...) and - hashlib.sha256(...) becomes functional. -""" - - -import md5 as _md5 -import sha as _sha1 - -try: - import Crypto -except ImportError: - _md4 = None - SHA256 = None -else: - from Crypto.Hash import MD4 as _md4 - if hasattr(Crypto, 'version_info'): # <- Available since v2.1.0alpha1 - from Crypto.Hash import SHA256 # SHA256 works since v2.1.0alpha1 - sha256 = SHA256.new - else: - SHA256 = None - del Crypto - - -compat = 0x01 -md5 = _md5.new -sha1 = _sha1.new - - -def new(name, string=''): - """Return a new hashing object using the named algorithm, optionally - initialized with the provided string. - """ - if name in ('md5', 'MD5'): - return _md5.new(string) - if name in ('sha1', 'SHA1'): - return _sha1.new(string) - if not _md4: - raise ValueError('unsupported hash type') - if name in ('md4', 'MD4'): - return _md4.new(string) - if name in ('sha256', 'SHA256') and SHA256: - return SHA256.new(string) - raise ValueError('unsupported hash type') diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/quotalimit.py --- a/VirtualMailManager/quotalimit.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,126 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2011 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.quotalimit - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's QuotaLimit class to manage quota limits - for domains and accounts. -""" - -from VirtualMailManager.pycompat import all - -_ = lambda msg: msg - - -class QuotaLimit(object): - """Class to handle quota limit specific data.""" - __slots__ = ('_dbh', '_qid', '_bytes', '_messages') - _kwargs = ('qid', 'bytes', 'messages') - - def __init__(self, dbh, **kwargs): - """Create a new QuotaLimit instance. - - Either the `qid` keyword or the `bytes` and `messages` keywords - must be specified. - - Arguments: - - `dbh` : pyPgSQL.PgSQL.Connection || psycopg2._psycopg.connection - A database connection for the database access. - - Keyword arguments: - - `qid` : int - The id of a quota limit - `bytes` : long - The quota limit in bytes. - `messages` : int - The quota limit in number of messages - """ - self._dbh = dbh - self._qid = 0 - self._bytes = 0 - self._messages = 0 - - for key in kwargs.iterkeys(): - if key not in self.__class__._kwargs: - raise ValueError('unrecognized keyword: %r' % key) - qid = kwargs.get('qid') - if qid is not None: - assert isinstance(qid, (int, long)) - self._load_by_qid(qid) - else: - bytes_, msgs = kwargs.get('bytes'), kwargs.get('messages') - assert all(isinstance(i, (int, long)) for i in (bytes_, msgs)) - if bytes_ < 0: - self._bytes = -bytes_ - else: - self._bytes = bytes_ - if msgs < 0: - self._messages = -msgs - else: - self._messages = msgs - self._load_by_limit() - - @property - def bytes(self): - """Quota limit in bytes.""" - return self._bytes - - @property - def messages(self): - """Quota limit in number of messages.""" - return self._messages - - @property - def qid(self): - """The quota limit's unique ID.""" - return self._qid - - def __eq__(self, other): - if isinstance(other, self.__class__): - return self._qid == other._qid - return NotImplemented - - def __ne__(self, other): - if isinstance(other, self.__class__): - return self._qid != other._qid - return NotImplemented - - def _load_by_limit(self): - """Load the quota limit by limit values from the database.""" - dbc = self._dbh.cursor() - dbc.execute('SELECT qid FROM quotalimit WHERE bytes = %s AND ' - 'messages = %s', (self._bytes, self._messages)) - res = dbc.fetchone() - dbc.close() - if res: - self._qid = res[0] - else: - self._save() - - def _load_by_qid(self, qid): - """Load the quota limit by its unique ID from the database.""" - dbc = self._dbh.cursor() - dbc.execute('SELECT bytes, messages FROM quotalimit WHERE qid = %s', - (qid,)) - res = dbc.fetchone() - dbc.close() - if not res: - raise ValueError('Unknown quota limit id specified: %r' % qid) - self._qid = qid - self._bytes, self._messages = res - - def _save(self): - """Store a new quota limit in the database.""" - dbc = self._dbh.cursor() - dbc.execute("SELECT nextval('quotalimit_id')") - self._qid = dbc.fetchone()[0] - dbc.execute('INSERT INTO quotalimit (qid, bytes, messages) VALUES ' - '(%s, %s, %s)', (self._qid, self._bytes, self._messages)) - self._dbh.commit() - dbc.close() - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/relocated.py --- a/VirtualMailManager/relocated.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2008 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.relocated - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's Relocated class to handle relocated users. -""" - -from VirtualMailManager.domain import get_gid -from VirtualMailManager.emailaddress import EmailAddress, \ - DestinationEmailAddress -from VirtualMailManager.errors import RelocatedError as RErr -from VirtualMailManager.constants import DOMAIN_INVALID, NO_SUCH_DOMAIN, \ - NO_SUCH_RELOCATED, RELOCATED_ADDR_DEST_IDENTICAL, RELOCATED_EXISTS - - -_ = lambda msg: msg - - -class Relocated(object): - """Class to handle e-mail addresses of relocated users.""" - __slots__ = ('_addr', '_dest', '_gid', '_dbh') - - def __init__(self, dbh, address): - """Creates a new *Relocated* instance. The ``address`` is the - old e-mail address of the user. - - Use `setDestination()` to set/update the new address, where the - user has moved to. - - """ - assert isinstance(address, EmailAddress) - self._addr = address - self._dbh = dbh - self._gid = get_gid(self._dbh, self._addr.domainname) - if not self._gid: - raise RErr(_(u"The domain '%s' does not exist.") % - self._addr.domainname, NO_SUCH_DOMAIN) - self._dest = None - - self._load() - - def __nonzero__(self): - """Returns `True` if the Relocated is known, `False` if it's new.""" - return self._dest is not None - - def _load(self): - """Loads the destination address from the database into the - `_dest` attribute. - - """ - dbc = self._dbh.cursor() - dbc.execute('SELECT destination FROM relocated WHERE gid = %s AND ' - 'address = %s', (self._gid, self._addr.localpart)) - destination = dbc.fetchone() - dbc.close() - if destination: - destination = DestinationEmailAddress(destination[0], self._dbh) - if destination.at_localhost: - raise RErr(_(u"The destination address' domain name must not " - u"be localhost."), DOMAIN_INVALID) - self._dest = destination - - @property - def address(self): - """The Relocated's EmailAddress instance.""" - return self._addr - - def set_destination(self, destination): - """Sets/updates the new address of the relocated user.""" - update = False - assert isinstance(destination, DestinationEmailAddress) - if destination.at_localhost: - raise RErr(_(u"The destination address' domain name must not be " - u"localhost."), DOMAIN_INVALID) - if self._addr == destination: - raise RErr(_(u'Address and destination are identical.'), - RELOCATED_ADDR_DEST_IDENTICAL) - if self._dest: - if self._dest == destination: - raise RErr(_(u"The relocated user '%s' already exists.") % - self._addr, RELOCATED_EXISTS) - else: - self._dest = destination - update = True - else: - self._dest = destination - - dbc = self._dbh.cursor() - if not update: - dbc.execute('INSERT INTO relocated (gid, address, destination) ' - 'VALUES (%s, %s, %s)', - (self._gid, self._addr.localpart, str(self._dest))) - else: - dbc.execute('UPDATE relocated SET destination = %s WHERE gid = %s ' - 'AND address = %s', - (str(self._dest), self._gid, self._addr.localpart)) - self._dbh.commit() - dbc.close() - - def get_info(self): - """Returns the address to which mails should be sent.""" - if not self._dest: - raise RErr(_(u"The relocated user '%s' does not exist.") % - self._addr, NO_SUCH_RELOCATED) - return self._dest - - def delete(self): - """Deletes the relocated entry from the database.""" - if not self._dest: - raise RErr(_(u"The relocated user '%s' does not exist.") % - self._addr, NO_SUCH_RELOCATED) - dbc = self._dbh.cursor() - dbc.execute('DELETE FROM relocated WHERE gid = %s AND address = %s', - (self._gid, self._addr.localpart)) - if dbc.rowcount > 0: - self._dbh.commit() - dbc.close() - self._dest = None - -del _ diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/serviceset.py --- a/VirtualMailManager/serviceset.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -# coding: utf-8 -# Copyright (c) 2011 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.serviceset - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's ServiceSet class for simplified database access - to the service_set table. -""" - -SERVICES = ('smtp', 'pop3', 'imap', 'sieve') - -cfg_dget = lambda option: None - - -class ServiceSet(object): - """A wrapper class that provides access to the service_set table. - - Each ServiceSet object provides following - read only - attributes: - - `ssid` : long - The id of the service set - `smtp` : bool - Boolean flag for service smtp - `pop3` : bool - Boolean flag for service pop3 - `imap` : bool - Boolean flag for service imap - `sieve` : bool - Boolean flag for service sieve - `services` : dict - The four services above with boolean values - """ - __slots__ = ('_ssid', '_services', '_sieve_col', '_dbh') - _kwargs = (('ssid',) + SERVICES) - - def __init__(self, dbh, **kwargs): - """Creates a new ServiceSet instance. - - Either the 'ssid' keyword argument or one or more of the service - arguments ('smtp', 'pop3', 'imap', 'sieve') must be provided. - - Arguments: - `dbh` : pyPgSQL.PgSQL.Connection or psycopg2.extensions.connection - A database connection for the database access. - - Keyword arguments: - `ssid` : int - The id of the service set (>0) - `smtp` : bool - Boolean flag for service smtp - default `True` - `pop3` : bool - Boolean flag for service pop3 - default `True` - `imap` : bool - Boolean flag for service imap - default `True` - `sieve` : bool - Boolean flag for service sieve - default `True` - """ - self._dbh = dbh - self._ssid = 0 - self._services = dict.fromkeys(SERVICES, True) - if cfg_dget('misc.dovecot_version') < 0x10200b02: - self._sieve_col = 'managesieve' - else: - self._sieve_col = 'sieve' - - for key in kwargs.iterkeys(): - if key not in self.__class__._kwargs: - raise ValueError('unrecognized keyword: %r' % key) - if key == 'ssid': - assert not isinstance(kwargs[key], bool) and \ - isinstance(kwargs[key], (int, long)) and kwargs[key] > 0 - self._load_by_ssid(kwargs[key]) - break - else: - assert isinstance(kwargs[key], bool) - if not kwargs[key]: - self._services[key] = kwargs[key] - if not self._ssid: - self._load_by_services() - - def __eq__(self, other): - if isinstance(other, self.__class__): - return self._ssid == other._ssid - return NotImplemented - - def __ne__(self, other): - if isinstance(other, self.__class__): - return self._ssid != other._ssid - return NotImplemented - - def __getattr__(self, name): - if name not in self.__class__._kwargs: - raise AttributeError('%r object has no attribute %r' % ( - self.__class__.__name__, name)) - if name == 'ssid': - return self._ssid - else: - return self._services[name] - - def __repr__(self): - return '%s(%s, %s)' % (self.__class__.__name__, self._dbh, - ', '.join('%s=%r' % s for s in self._services.iteritems())) - - def _load_by_services(self): - """Try to load the service_set by it's service combination.""" - sql = ('SELECT ssid FROM service_set WHERE %s' % - ' AND '.join('%s = %s' % - (k, str(v).upper()) for k, v in self._services.iteritems())) - if self._sieve_col == 'managesieve': - sql = sql.replace('sieve', self._sieve_col) - dbc = self._dbh.cursor() - dbc.execute(sql) - result = dbc.fetchone() - dbc.close() - if result: - self._ssid = result[0] - else: - self._save() - - def _load_by_ssid(self, ssid): - """Try to load the service_set by it's primary key.""" - dbc = self._dbh.cursor() - dbc.execute('SELECT ssid, smtp, pop3, imap, %s' % (self._sieve_col,) + - ' FROM service_set WHERE ssid = %s', (ssid,)) - result = dbc.fetchone() - dbc.close() - if not result: - raise ValueError('Unknown service_set id specified: %r' % ssid) - self._ssid = result[0] - #self._services.update(zip(SERVICES, result[1:])) - for key, value in zip(SERVICES, result[1:]): # pyPgSQL compatible - if value: - self._services[key] = True - else: - self._services[key] = False - - def _save(self): - """Store a new service_set in the database.""" - sql = ('INSERT INTO service_set (ssid, smtp, pop3, imap, %s) ' % - (self._sieve_col,) + - 'VALUES (%(ssid)s, %(smtp)s, %(pop3)s, %(imap)s, %(sieve)s)') - self._set_ssid() - values = {'ssid': self._ssid} - values.update(self._services) - dbc = self._dbh.cursor() - dbc.execute(sql, values) - self._dbh.commit() - dbc.close() - - def _set_ssid(self): - """Set the unique ID for the new service_set.""" - assert self._ssid == 0 - dbc = self._dbh.cursor() - dbc.execute("SELECT nextval('service_set_id')") - self._ssid = dbc.fetchone()[0] - dbc.close() - - @property - def services(self): - """A dictionary: Keys: `smtp`, `pop3`, `imap` and `sieve` with - boolean values.""" - return self._services.copy() - -del cfg_dget diff -r 659c4476c57c -r b678a1c43027 VirtualMailManager/transport.py --- a/VirtualMailManager/transport.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -# -*- coding: UTF-8 -*- -# Copyright (c) 2008 - 2014, Pascal Volk -# See COPYING for distribution information. -""" - VirtualMailManager.transport - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Virtual Mail Manager's Transport class to manage the transport for - domains and accounts. -""" - -from VirtualMailManager.pycompat import any - -_ = lambda msg: msg - - -class Transport(object): - """A wrapper class that provides access to the transport table""" - __slots__ = ('_tid', '_transport', '_dbh') - - def __init__(self, dbh, tid=None, transport=None): - """Creates a new Transport instance. - - Either tid or transport must be specified. When both arguments - are given, tid will be used. - - Keyword arguments: - dbh -- a pyPgSQL.PgSQL.connection - tid -- the id of a transport (int/long) - transport -- the value of the transport (str) - - """ - self._dbh = dbh - self._tid = 0 - assert any((tid, transport)) - if tid: - assert not isinstance(tid, bool) and isinstance(tid, (int, long)) - self._load_by_id(tid) - else: - assert isinstance(transport, basestring) - self._transport = transport - self._load_by_name() - - @property - def tid(self): - """The transport's unique ID.""" - return self._tid - - @property - def transport(self): - """The transport's value, ex: 'dovecot:'""" - return self._transport - - def __eq__(self, other): - if isinstance(other, self.__class__): - return self._tid == other._tid - return NotImplemented - - def __ne__(self, other): - if isinstance(other, self.__class__): - return self._tid != other._tid - return NotImplemented - - def __str__(self): - return self._transport - - def _load_by_id(self, tid): - """load a transport by its id from the database""" - dbc = self._dbh.cursor() - dbc.execute('SELECT transport FROM transport WHERE tid = %s', (tid,)) - result = dbc.fetchone() - dbc.close() - if not result: - raise ValueError('Unknown transport id specified: %r' % tid) - self._transport = result[0] - self._tid = tid - - def _load_by_name(self): - """Load a transport by its transport name from the database.""" - dbc = self._dbh.cursor() - dbc.execute('SELECT tid FROM transport WHERE transport = %s', - (self._transport,)) - result = dbc.fetchone() - dbc.close() - if result: - self._tid = result[0] - else: - self._save() - - def _save(self): - """Save the new transport in the database.""" - dbc = self._dbh.cursor() - dbc.execute("SELECT nextval('transport_id')") - self._tid = dbc.fetchone()[0] - dbc.execute('INSERT INTO transport (tid, transport) VALUES (%s, %s)', - (self._tid, self._transport)) - self._dbh.commit() - dbc.close() - -del _ diff -r 659c4476c57c -r b678a1c43027 doc/api/Makefile --- a/doc/api/Makefile Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest - -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/vmm.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/vmm.qhc" - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ - "run these through (pdf)latex." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff -r 659c4476c57c -r b678a1c43027 doc/api/source/conf.py --- a/doc/api/source/conf.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -# -*- coding: utf-8 -*- -# -# vmm documentation build configuration file, created by -# sphinx-quickstart on Sun Feb 14 00:08:08 2010. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.append(os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['.templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'vmm' -copyright = u'2010, Pascal Volk' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0.6' -# The full version, including alpha/beta/rc tags. -release = '0.6.x' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of documents that shouldn't be included in the build. -#unused_docs = [] - -# List of directories, relative to source directory, that shouldn't be searched -# for source files. -exclude_trees = [] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. Major themes that come with -# Sphinx are currently 'default' and 'sphinxdoc'. -html_theme = 'default' -#html_theme = 'sphinxdoc' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# "<project> v<release> documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['.static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_use_modindex = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a <link> tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = '' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'vmmdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'vmm.tex', u'vmm Documentation', - u'Pascal Volk', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_use_modindex = True - - -# Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'http://docs.python.org/': None} - -todo_include_todos = True diff -r 659c4476c57c -r b678a1c43027 doc/api/source/index.rst --- a/doc/api/source/index.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -====================== -VirtualMailManager API -====================== - -:Author: Pascal Volk <neverseen@users.sourceforge.net> -:Date: |today| -:Release: |version| - -Contents: - -.. toctree:: - :maxdepth: 1 - :numbered: - - vmm.rst - vmm_config.rst - vmm_emailaddress.rst - vmm_alias.rst - vmm_relocated.rst - vmm_errors.rst - vmm_constants_error.rst - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff -r 659c4476c57c -r b678a1c43027 doc/api/source/vmm.rst --- a/doc/api/source/vmm.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -:mod:`VirtualMailManager` --- Initialization code and some functions -===================================================================== - -.. module:: VirtualMailManager - :synopsis: Initialization code and some functions - -.. moduleauthor:: Pascal Volk <neverseen@users.sourceforge.net> - -.. toctree:: - :maxdepth: 2 - -When the VirtualMailManager module, or one of its sub modules, is imported, -the following actions will be performed: - - - :func:`locale.setlocale` (with :const:`locale.LC_ALL`) is called, to set - :const:`ENCODING` - - :func:`gettext.install` is called, to have 18N support. - -Constants and data ------------------- - -.. data:: ENCODING - - The systems current character encoding, e.g. ``'UTF-8'`` or - ``'ANSI_X3.4-1968'`` (aka ASCII). - - -Functions ---------- - -.. function:: ace2idna(domainname) - - Converts the idn domain name *domainname* into punycode. - - :param domainname: the domain-ace representation (``xn--…``) - :type domainname: str - :rtype: unicode - -.. function:: check_domainname(domainname) - - Returns the validated domain name *domainname*. - - It also converts the name of the domain from IDN to ASCII, if necessary. - - :param domainname: the name of the domain - :type domainname: :obj:`basestring` - :rtype: str - :raise VirtualMailManager.errors.VMMError: if the domain name is - too long or doesn't look like a valid domain name (label.label.label). - -.. function:: check_localpart(localpart) - - Returns the validated local-part *localpart* of an e-mail address. - - :param localpart: The local-part of an e-mail address. - :type localpart: str - :rtype: str - :raise VirtualMailManager.errors.VMMError: if the local-part is too - long or contains invalid characters. - -.. function:: exec_ok(binary) - - Checks if the *binary* exists and if it is executable. - - :param binary: path to the binary - :type binary: str - :rtype: str - :raise VirtualMailManager.errors.VMMError: if *binary* isn't a file - or is not executable. - -.. function:: expand_path(path) - - Expands paths, starting with ``.`` or ``~``, to an absolute path. - - :param path: Path to a file or directory - :type path: str - :rtype: str - -.. function:: get_unicode(string) - - Converts `string` to `unicode`, if necessary. - - :param string: The string taht should be converted - :type string: str - :rtype: unicode - -.. function:: idn2ascii(domainname) - - Converts the idn domain name *domainname* into punycode. - - :param domainname: the unicode representation of the domain name - :type domainname: unicode - :rtype: str - -.. function:: is_dir(path) - - Checks if *path* is a directory. - - :param path: Path to a directory - :type path: str - :rtype: str - :raise VirtualMailManager.errors.VMMError: if *path* is not a directory. - - -Examples --------- - - >>> from VirtualMailManager import * - >>> ace2idna('xn--pypal-4ve.tld') - u'p\u0430ypal.tld' - >>> idn2ascii(u'öko.de') - 'xn--ko-eka.de' - >>> check_domainname(u'pаypal.tld') - 'xn--pypal-4ve.tld' - >>> check_localpart('john.doe') - 'john.doe' - >>> exec_ok('usr/bin/vim') - Traceback (most recent call last): - File "<stdin>", line 1, in <module> - File "./VirtualMailManager/__init__.py", line 93, in exec_ok - NO_SUCH_BINARY) - VirtualMailManager.errors.VMMError: 'usr/bin/vim' is not a file - >>> exec_ok('/usr/bin/vim') - '/usr/bin/vim' - >>> expand_path('.') - '/home/user/hg/vmm' - >>> get_unicode('hello world') - u'hello world' - >>> is_dir('~/hg') - '/home/user/hg' - >>> - diff -r 659c4476c57c -r b678a1c43027 doc/api/source/vmm_alias.rst --- a/doc/api/source/vmm_alias.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -:mod:`VirtualMailManager.Alias` --- Handling of alias e-mail addresses -====================================================================== - -.. module:: VirtualMailManager.Alias - :synopsis: Handling of alias e-mail addresses - -.. moduleauthor:: Pascal Volk <neverseen@users.sourceforge.net> - -.. toctree:: - :maxdepth: 2 - - -This module provides the :class:`Alias` class. The data are read from/stored -in the ``alias`` table. This table is used by Postfix to rewrite recipient -addresses. - - -Alias ---------- -.. class:: Alias(dbh, address) - - Creates a new *Alias* instance. Alias instances provides the :func:`__len__` - method. So the existence of an alias in the database can be tested with a - simple if condition. - - :param dbh: a database connection - :type dbh: :class:`pyPgSQL.PgSQL.Connection` - :param address: the alias e-mail address. - :type address: :class:`VirtualMailManager.EmailAddress.EmailAddress` - - .. method:: add_destinations(destinations, expansion_limit [, warnings=None]) - - Adds the *destinations* to the destinations of the alias. This method - returns a ``set`` of all addresses which successfully were stored into the - database. - - If one of the e-mail addresses in *destinations* is the same as the alias - address, it will be silently discarded. Destination addresses, that are - already assigned to the alias, will be also ignored. - - When the optional *warnings* list is given, all ignored addresses will be - appended to it. - - :param destinations: The destination addresses of the alias - :type destinations: :obj:`list` of - :class:`VirtualMailManager.EmailAddress.EmailAddress` instances - :param expansion_limit: The maximal number of destinations (see also: - `virtual_alias_expansion_limit - <http://www.postfix.org/postconf.5.html#virtual_alias_expansion_limit>`_) - :type expansion_limit: :obj:`int` - :param warnings: A optional list, to record all ignored addresses - :type warnings: :obj:`list` - :rtype: :obj:`set` - :raise VirtualMailManager.errors.AliasError: if the additional - *destinations* will exceed the *expansion_limit* or if the alias - already exceeds its *expansion_limit*. - - .. seealso:: :mod:`VirtualMailManager.ext.postconf` -- to read actual - values of Postfix configuration parameters. - - - .. method:: del_destination(destination) - - Deletes the given *destination* address from the alias. - - :param destination: a destination address of the alias - :type destination: :class:`VirtualMailManager.EmailAddress.EmailAddress` - :rtype: :obj:`None` - :raise VirtualMailManager.errors.AliasError: if the destination wasn't - assigned to the alias or the alias doesn't exist. - - - .. method:: delete() - - Deletes the alias with all its destinations. - - :rtype: :obj:`None` - :raise VirtualMailManager.errors.AliasError: if the alias doesn't exist. - - - .. method:: get_destinations() - - Returns an iterator for all destinations (``EmailAddress`` instances) of - the alias. - - :rtype: :obj:`listiterator` - :raise VirtualMailManager.errors.AliasError: if the alias doesn't exist. diff -r 659c4476c57c -r b678a1c43027 doc/api/source/vmm_config.rst --- a/doc/api/source/vmm_config.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,275 +0,0 @@ -:mod:`VirtualMailManager.Config` --- Simplified configuration access -====================================================================== - -.. module:: VirtualMailManager.Config - :synopsis: Simplified configuration access - -.. moduleauthor:: Pascal Volk <neverseen@users.sourceforge.net> - -.. toctree:: - :maxdepth: 2 - - -This module provides a few classes for simplified configuration handling -and the validation of the setting's *type* and *value*. - -:class:`LazyConfig` is derived from Python's -:class:`ConfigParser.RawConfigParser`. It doesn't use ``RawConfigParser``'s -``DEFAULT`` section. All settings and their defaults, if supposed, are -handled by :class:`LazyConfigOption` objects in the :attr:`LazyConfig._cfg` -*dict*. - -``LazyConfig``'s setters and getters for options are taking a single string -for the *section* and *option* argument, e.g. ``config.pget('database.user')`` -instead of ``config.get('database', 'user')``. - - - -LazyConfig ----------- -.. class:: LazyConfig - - Bases: :class:`ConfigParser.RawConfigParser` - - .. versionadded:: 0.6.0 - - .. attribute:: _cfg - - a multi dimensional :class:`dict`, containing *sections* and *options*, - represented by :class:`LazyConfigOption` objects. - - For example:: - - from VirtualMailManager.Config import LazyConfig, LazyConfigOption - - class FooConfig(LazyConfig): - def __init__(self, ...): - LazyConfig.__init__(self) - ... - LCO = LazyConfigOption - self._cfg = { - 'database': {# section database: - 'host': LCO(str, '::1', self.get), # options of the - 'name': LCO(str, 'dbx', self.get), # database section. - 'pass': LCO(str, None, self.get), # No defaults for the - 'user': LCO(str, None, self.get), # user and pass options - } - } - - ... - - - .. method:: bool_new(value) - - Converts the string *value* into a `bool` and returns it. - - | ``'1'``, ``'on'``, ``'yes'`` and ``'true'`` will become :const:`True` - | ``'0'``, ``'off'``, ``'no'`` and ``'false'`` will become :const:`False` - - :param value: one of the above mentioned strings - :type value: :obj:`basestring` - :rtype: bool - :raise ConfigValueError: for all other values, except ``bool``\ s - - .. method:: dget(option) - - Like :meth:`pget`, but returns the *option*'s default value, from - :attr:`_cfg` (defined by :attr:`LazyConfigOption.default`) if the *option* - is not configured in a ini-like configuration file. - - :param option: the section.option combination - :type option: :obj:`basestring` - :raise NoDefaultError: if the *option* couldn't be found in the - configuration file and no default value was passed to - :class:`LazyConfigOption`'s constructor for the requested *option*. - - .. method:: getboolean(section, option) - - Returns the boolean value of the *option*, in the given *section*. - - For a boolean :const:`True`, the value must be set to ``'1'``, ``'on'``, - ``'yes'``, ``'true'`` or :const:`True`. For a boolean :const:`False`, the - value must set to ``'0'``, ``'off'``, ``'no'``, ``'false'`` or - :const:`False`. - - :param section: The section's name - :type section: :obj:`basestring` - :param option: The option's name - :type option: :obj:`basestring` - :rtype: bool - :raise ValueError: if the option has an other value than the values - mentioned above. - - .. method:: has_option(option) - - Checks if the *option* (section\ **.**\ option) is a known configuration - option. - - :param option: The option's name - :type option: :obj:`basestring` - :rtype: bool - - .. method:: has_section(section) - - Checks if *section* is a known configuration section. - - :param section: The section's name - :type section: :obj:`basestring` - :rtype: bool - - .. method:: items(section) - - Returns an iterator for ``key, value`` :obj:`tuple`\ s for each option in - the given *section*. - - :param section: The section's name - :type section: :obj:`basestring` - :raise NoSectionError: if the given *section* is not known. - - .. method:: pget(option) - - Polymorphic getter which returns the *option*'s value (by calling - :attr:`LazyConfigOption.getter`) with the appropriate type, defined by - :attr:`LazyConfigOption.cls`. - - :param option: the section.option combination - :type option: :obj:`basestring` - - .. method:: sections() - - Returns an iterator object for all configuration sections from the - :attr:`_cfg` dictionary. - - :rtype: :obj:`dictionary-keyiterator` - - .. method:: set(option, value) - - Like :meth:`ConfigParser.RawConfigParser.set`, but converts the *option*'s - new *value* (by calling :attr:`LazyConfigOption.cls`) to the appropriate - type/class. When the ``LazyConfigOption``'s optional parameter *validate* - was not :const:`None`, the new *value* will be also validated. - - :param option: the section.option combination - :type option: :obj:`basestring` - :param value: the new value to be set - :type value: :obj:`basestring` - :rtype: :const:`None` - :raise ConfigValueError: if a boolean value shout be set (:meth:`bool_new`) - and it fails - :raise ValueError: if an other setter (:attr:`LazyConfigOption.cls`) or - validator (:attr:`LazyConfigOption.validate`) fails. - :raise VirtualMailManager.errors.VMMError: if - :attr:`LazyConfigOption.validate` is set to - :func:`VirtualMailManager.exec_ok` or :func:`VirtualMailManager.is_dir`. - - -LazyConfigOption ----------------- -LazyConfigOption instances are required by :class:`LazyConfig` instances, and -instances of classes derived from `LazyConfig`, like the :class:`Config` -class. - -.. class:: LazyConfigOption (cls, default, getter[, validate=None]) - - .. versionadded:: 0.6.0 - - The constructor's parameters are: - - ``cls`` : :obj:`type` - The class/type of the option's value. - ``default`` : :obj:`str` or the one defined by ``cls`` - Default value of the option. Use :const:`None` if the option shouldn't - have a default value. - ``getter``: :obj:`callable` - A method's name of :class:`ConfigParser.RawConfigParser` and derived - classes, to get a option's value, e.g. `self.getint`. - ``validate`` : :obj:`callable` or :const:`None` - :const:`None` or any function, which takes one argument and returns the - validated argument with the appropriate type (for example: - :meth:`LazyConfig.bool_new`). The function should raise a - :exc:`ConfigValueError` if the validation fails. This function checks the - new value when :meth:`LazyConfig.set()` is called. - - Each LazyConfigOption object has the following read-only attributes: - - .. attribute:: cls - - The class of the option's value e.g. `str`, `unicode` or `bool`. Used as - setter method when :meth:`LazyConfig.set` (or the ``set()`` method of a - derived class) is called. - - .. attribute:: default - - The option's default value, may be ``None`` - - .. attribute:: getter - - A method's name of :class:`ConfigParser.RawConfigParser` and derived - classes, to get a option's value, e.g. ``self.getint``. - - .. attribute:: validate - - A method or function to validate the option's new value. - - -Config ------- -The final configuration class of the virtual mail manager. - -.. class:: Config (filename) - - Bases: :class:`LazyConfig` - - :param filename: absolute path to the configuration file. - :type filename: :obj:`basestring` - - .. attribute:: _cfg - - The configuration ``dict``, containing all configuration sections and - options, as described in :attr:`LazyConfig._cfg`. - - .. method:: check() - - Checks all section's options for settings w/o a default value. - - :raise VirtualMailManager.errors.ConfigError: if the check fails - - .. method:: load() - - Loads the configuration read-only. - - :raise VirtualMailManager.errors.ConfigError: if the - configuration syntax is invalid - - .. method:: unicode(section, option) - - Returns the value of the *option* from *section*, converted to Unicode. - This method is intended for the :attr:`LazyConfigOption.getter`. - - :param section: The name of the configuration section - :type section: :obj:`basestring` - :param option: The name of the configuration option - :type option: :obj:`basestring` - :rtype: :obj:`unicode` - - -Exceptions ----------- - -.. exception:: BadOptionError(msg) - - Bases: :exc:`ConfigParser.Error` - - Raised when a option isn't in the format 'section.option'. - -.. exception:: ConfigValueError(msg) - - Bases: :exc:`ConfigParser.Error` - - Raised when creating or validating of new values fails. - -.. exception:: NoDefaultError(section, option) - - Bases: :exc:`ConfigParser.Error` - - Raised when the requested option has no default value. diff -r 659c4476c57c -r b678a1c43027 doc/api/source/vmm_constants_error.rst --- a/doc/api/source/vmm_constants_error.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,227 +0,0 @@ -:mod:`VirtualMailManager.constants.ERROR` --- Error codes -========================================================= - -.. module:: VirtualMailManager.constants.ERROR - :synopsis: VirtualMailManager's error codes - -.. moduleauthor:: Pascal Volk <neverseen@users.sourceforge.net> - -.. toctree:: - :maxdepth: 2 - -Error codes, used by all :mod:`VirtualMailManager.errors`. - -.. data:: ACCOUNT_AND_ALIAS_PRESENT - - Can't delete the Domain - there are accounts and aliases assigned - -.. data:: ACCOUNT_EXISTS - - The Account exists already - -.. data:: ACCOUNT_PRESENT - - Can't delete the Domain - there are accounts - -.. data:: ALIASDOMAIN_EXISTS - - Can't save/switch the destination of the AliasDomain - old and new destination - are the same. - -.. data:: ALIASDOMAIN_ISDOMAIN - - Can't create AliasDomain - there is already a Domain with the given name - - .. todo:: Move the related check to the Handler class - -.. data:: ALIASDOMAIN_NO_DOMDEST - - Can't save/switch the destination of an AliasDomain if the destination was - omitted - -.. data:: ALIAS_ADDR_DEST_IDENTICAL - - The alias address and its destination are the same - - obsolete? - -.. data:: ALIAS_EXCEEDS_EXPANSION_LIMIT - - The Alias has reached or exceeds its expansion limit - -.. data:: ALIAS_EXISTS - - Alias with the given destination exists already - - obsolete? - -.. data:: ALIAS_MISSING_DEST - - obsolete? - -.. data:: ALIAS_PRESENT - - Can't delete Domain or Account - there are aliases assigned - -.. data:: CONF_ERROR - - Syntax error in the configuration file or missing settings w/o a default value - -.. data:: CONF_NOFILE - - The configuration file couldn't be found - -.. data:: CONF_NOPERM - - The user's permissions are insufficient - -.. data:: CONF_WRONGPERM - - Configuration file has the wrong access mode - -.. data:: DATABASE_ERROR - - A database error occurred - -.. data:: DOMAINDIR_GROUP_MISMATCH - - Domain directory is owned by the wrong group - -.. data:: DOMAIN_ALIAS_EXISTS - - Can't create Domain - there is already an AliasDomain with the same name - - .. todo:: Move the related check to the Handler class - -.. data:: DOMAIN_EXISTS - - The Domain is already available in the database - -.. data:: DOMAIN_INVALID - - The domain name is invalid - -.. data:: DOMAIN_NO_NAME - - Missing the domain name - -.. data:: DOMAIN_TOO_LONG - - The length of domain is > 255 - -.. data:: FOUND_DOTS_IN_PATH - - Can't delete directory with ``.`` or ``..`` in path - - .. todo:: check if we can solve this issue with expand_path() - -.. data:: INVALID_ADDRESS - - The specified value doesn't look like a e-mail address - -.. data:: INVALID_AGUMENT - - The given argument is invalid - -.. data:: INVALID_OPTION - - The given option is invalid - -.. data:: INVALID_SECTION - - The section is not a known configuration section - -.. data:: LOCALPART_INVALID - - The local-part of an e-mail address was omitted or is invalid - -.. data:: LOCALPART_TOO_LONG - - The local-part (w/o a extension) is too long (> 64) - -.. data:: MAILDIR_PERM_MISMATCH - - The Maildir is owned by the wrong user/group - -.. data:: MAILLOCATION_INIT - - Can't create a new MailLocation instance - - obsolete? - -.. data:: NOT_EXECUTABLE - - The binary is not executable - -.. data:: NO_SUCH_ACCOUNT - - No Account with the given e-mail address - -.. data:: NO_SUCH_ALIAS - - No Alias with the given e-mail address - -.. data:: NO_SUCH_ALIASDOMAIN - - The given domain is not an AliasDomain - -.. data:: NO_SUCH_BINARY - - Can't find the file at the specified location - -.. data:: NO_SUCH_DIRECTORY - - There is no directory with the given path - -.. data:: NO_SUCH_DOMAIN - - No Domain with the given name - -.. data:: NO_SUCH_RELOCATED - - There is no Relocated user with the given e-mail address - -.. data:: RELOCATED_ADDR_DEST_IDENTICAL - - The e-mail address of the Relocated user an its destination are the same - -.. data:: RELOCATED_EXISTS - - Can't create Account or Alias, there is already a Relocated user with the - given e-mail address - -.. data:: RELOCATED_MISSING_DEST - - obsolete? - -.. data:: TRANSPORT_INIT - - Can't initialize a new Transport instance - - obsolete? - -.. data:: UNKNOWN_MAILLOCATION_ID - - There is no MailLocation entry with the given ID - - obsolete? - -.. data:: UNKNOWN_SERVICE - - The specified service is unknown - -.. data:: UNKNOWN_TRANSPORT_ID - - There is no Transport entry with the given ID - -.. data:: UNKNOWN_MAILLOCATION_NAME - - The given mail_location directory couldn't be accepted - -.. data:: VMM_ERROR - - Internal error - -.. data:: VMM_TOO_MANY_FAILURES - - Too many errors in interactive mode diff -r 659c4476c57c -r b678a1c43027 doc/api/source/vmm_emailaddress.rst --- a/doc/api/source/vmm_emailaddress.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -:mod:`VirtualMailManager.EmailAddress` --- Handling of e-mail addresses -======================================================================= - -.. module:: VirtualMailManager.EmailAddress - :synopsis: Handling of e-mail addresses - -.. moduleauthor:: Pascal Volk <neverseen@users.sourceforge.net> - -.. toctree:: - :maxdepth: 2 - - -This module provides the :class:`EmailAddress` class to handle validated e-mail -addresses. - - -EmailAddress ------------- - -.. class:: EmailAddress(address) - - Creates a new EmailAddress instance. - - :param address: string representation of an e-mail addresses - :type address: :obj:`basestring` - :raise VirtualMailManager.errors.EmailAddressError: if the - *address* is syntactically wrong. - :raise VirtualMailManager.errors.VMMError: if the validation of the - local-part or domain name fails. - - An EmailAddress instance has the both read-only attributes: - - .. attribute:: localpart - - The local-part of the address *local-part@domain* - - - .. attribute:: domainname - - The domain part of the address *local-part@domain* - - -Examples --------- - - >>> from VirtualMailManager.EmailAddress import EmailAddress - >>> john = EmailAddress('john.doe@example.com') - >>> john.localpart - 'john.doe' - >>> john.domainname - 'example.com' - >>> jane = EmailAddress('jane.doe@example.com') - >>> jane != john - True - >>> EmailAddress('info@xn--pypal-4ve.tld') == EmailAddress(u'info@pаypal.tld') - True - >>> jane - EmailAddress('jane.doe@example.com') - >>> print john - john.doe@example.com - >>> diff -r 659c4476c57c -r b678a1c43027 doc/api/source/vmm_errors.rst --- a/doc/api/source/vmm_errors.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,122 +0,0 @@ -:mod:`VirtualMailManager.errors` --- Exception classes -====================================================== - -.. module:: VirtualMailManager.errors - :synopsis: Exception classes - -.. moduleauthor:: Pascal Volk <neverseen@users.sourceforge.net> - -.. toctree:: - :maxdepth: 2 - -Exceptions, used by VirtualMailManager's classes. - - -Exceptions ----------- - -.. exception:: VMMError(msg, code) - - Bases: :exc:`exceptions.Exception` - - :param msg: the error message - :type msg: :obj:`basestring` - :param code: the error code (one of :mod:`VirtualMailManager.constants.ERROR`) - :type code: :obj:`int` - - Base class for all other Exceptions in the VirtualMailManager package. - - The *msg* and *code* are accessible via the both attributes: - - .. attribute:: msg - - The error message of the exception. - - - .. attribute:: code - - The numerical error code of the exception. - - -.. exception:: ConfigError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for configuration (:mod:`VirtualMailManager.Config`) - exceptions. - - -.. exception:: PermissionError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for file permission exceptions. - - -.. exception:: NotRootError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for non-root exceptions. - - -.. exception:: DomainError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for Domain (:mod:`VirtualMailManager.Domain`) exceptions. - - -.. exception:: AliasDomainError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for AliasDomain (:mod:`VirtualMailManager.AliasDomain`) - exceptions. - - -.. exception:: AccountError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for Account (:mod:`VirtualMailManager.Account`) exceptions. - - -.. exception:: AliasError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for Alias (:mod:`VirtualMailManager.Alias`) exceptions. - - -.. exception:: EmailAddressError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for EmailAddress (:mod:`VirtualMailManager.EmailAddress`) - exceptions. - - -.. exception:: MailLocationError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for MailLocation (:mod:`VirtualMailManager.MailLocation`) - exceptions. - - -.. exception:: RelocatedError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for Relocated (:mod:`VirtualMailManager.Relocated`) - exceptions. - - -.. exception:: TransportError(msg, code) - - Bases: :exc:`VirtualMailManager.errors.VMMError` - - Exception class for Transport (:mod:`VirtualMailManager.Transport`) - exceptions. - diff -r 659c4476c57c -r b678a1c43027 doc/api/source/vmm_relocated.rst --- a/doc/api/source/vmm_relocated.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -:mod:`VirtualMailManager.Relocated` --- Handling of relocated users -=================================================================== - -.. module:: VirtualMailManager.Relocated - :synopsis: Handling of relocated users - -.. moduleauthor:: Pascal Volk <neverseen@users.sourceforge.net> - -.. toctree:: - :maxdepth: 2 - - -This module provides the :class:`Relocated` class. The data are read -from/stored in the ``relocated`` table. An optional lookup table, used -by Postfix for the "``user has moved to new_location``" reject/bounce message. - - -Relocated ---------- -.. class:: Relocated(dbh, address) - - Creates a new *Relocated* instance. If the relocated user with the given - *address* is already stored in the database use :meth:`get_info` to get the - destination address of the relocated user. To set or update the destination - of the relocated user use :meth:`set_destination`. Use :meth:`delete` in - order to delete the relocated user from the database. - - :param dbh: a database connection - :type dbh: :class:`pyPgSQL.PgSQL.Connection` - :param address: the e-mail address of the relocated user. - :type address: :class:`VirtualMailManager.EmailAddress.EmailAddress` - - - .. method:: delete() - - :rtype: :obj:`None` - :raise VirtualMailManager.errors.RelocatedError: if the relocated user - doesn't exist. - - Deletes the relocated user from the database. - - - .. method:: get_info() - - :rtype: :class:`VirtualMailManager.EmailAddress.EmailAddress` - :raise VirtualMailManager.errors.RelocatedError: if the relocated user - doesn't exist. - - Returns the destination e-mail address of the relocated user. - - - .. method:: set_destination(destination) - - :param destination: the new address where the relocated user has moved to - :type destination: :class:`VirtualMailManager.EmailAddress.EmailAddress` - :rtype: :obj:`None` - :raise VirtualMailManager.errors.RelocatedError: if the *destination* - address is already saved or is the same as the relocated user's address. - - Sets or updates the *destination* address of the relocated user. diff -r 659c4476c57c -r b678a1c43027 doc/web/Makefile --- a/doc/web/Makefile Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/vmm.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/vmm.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/vmm" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/vmm" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff -r 659c4476c57c -r b678a1c43027 doc/web/source/_static/local.conf --- a/doc/web/source/_static/local.conf Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -# A minimal configuration for a vmm setup with Dovecot v2.x. -# -# You could save this file as local.conf in the dovecot configuration directory -# (commonly /etc/dovecot or /usr/local/etc/dovecot). -# When you want to use this file as your configuration file for Dovecot, make -# sure you have commented out the line "!include conf.d/*.conf". The last line -# "!include_try local.conf" is sufficient. - -### -# conf.d/10-auth.conf -### -auth_mechanisms = plain login cram-md5 -passdb { - driver = sql - args = /usr/local/etc/dovecot/dovecot-sql.conf.ext -} -userdb { - driver = sql - args = /usr/local/etc/dovecot/dovecot-sql.conf.ext -} -#!include auth-system.conf.ext - -### -# conf.d/10-mail.conf -### -first_valid_gid = 70000 -first_valid_uid = 70000 -mail_access_groups = dovemail -mail_location = maildir:~/Maildir - -# uncomment if you want to use the quota plugin -#mail_plugins = quota - -### -# conf.d/10-master.conf -### - -# if you don't want to use secure imap, you have to disable the imaps listener -##service imap-login { -## inet_listener imaps { -## port = 0 -## } -##} - -service lmtp { - unix_listener /var/spool/postfix/private/dovecot-lmtp { - user = postfix - group = postfix - mode = 0600 - } -} - -service auth { - user = doveauth - unix_listener auth-userdb { - } - unix_listener /var/spool/postfix/private/dovecot-auth { - user = postfix - group = postfix - mode = 0600 - } -} - -service auth-worker { - unix_listener auth-worker { - user = doveauth - group = $default_internal_user - mode = 0660 - } - user = doveauth -} - -service dict { - unix_listener dict { - group = dovemail - mode = 0660 - } -} - -### -# conf.d/10-ssl.conf -### -# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt> -#ssl = yes - -ssl_cert = </etc/ssl/certs/dovecot.pem -ssl_key = </etc/ssl/private/dovecot.pem - -# if you want to disable SSL/TLS, you have set 'ssl = no' and disable the -# imaps listener in conf.d/10-master.conf - -### -# conf.d/15-lda.conf -### -postmaster_address = postmaster@YOUR-DOMAIN.TLD -recipient_delimiter = + -protocol lda { - # uncomment if you want to use the quota plugin - #mail_plugins = $mail_plugins - # uncomment if you want to use the quota and sieve plugins - #mail_plugins = $mail_plugins sieve -} - -### -# conf.d/20-imap.conf -### -protocol imap { - # uncomment if you want to use the quota plugin - #mail_plugins = $mail_plugins imap_quota -} - -### -# conf.d/20-lmtp.conf -### -protocol lmtp { - # uncomment if you want to use the quota plugin - #mail_plugins = $mail_plugins - # uncomment if you want to use the quota and sieve plugins - #mail_plugins = $mail_plugins sieve -} - -### -# conf.d/90-quota.conf -### -# uncomment if you want to use the quota plugin -#plugin { -# quota = dict:user:%{uid}:proxy::quota -# quota_rule = *:storage=0:messages=0 -# quota_rule2 = Trash:storage=+100M -#} - -### -# conf.d/90-sieve.conf -### -# uncomment if you want to use sieve (and maybe managesieve) -#plugin { -# recipient_delimiter = + -# sieve = ~/.dovecot.sieve -# sieve_dir = ~/sieve -#} diff -r 659c4476c57c -r b678a1c43027 doc/web/source/_static/vmm.cfg --- a/doc/web/source/_static/vmm.cfg Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -# This is the vmm (a virtual mail manager) configuration file. -# default location: /usr/local/etc/vmm.cfg -# - -# -# Database settings -# -[database] -; The Python PostgreSQL database adapter module to be used (String) -; Supported modules are: -; * psycopg2 -; * pyPgSQL -module = psycopg2 -; Hostname or IP address of the database server (String) -host = localhost -; The TCP port, on which the database server is listening for connections (Int) -port = 5432 -; SSL mode for the database connection (String) -; Possible values are: -; * disabled -; * allow -; * prefer (default) -; * require -; * verify-ca (PostgreSQL >= 8.4) -; * verify-full (PostgreSQL >= 8.4) -sslmode = prefer -; Database user name (String) -user = vmm -; Database password (String) -pass = dbpassword -; Database name (String) -name = mailsys - -# -# mailbox settings -# -[mailbox] -; The mailbox format to be used for user's mailboxes. (String) -; Depending on the used Dovecot version there are up to 3 supported formats: -; * maildir - since Dovecot v1.0.0 -; * mdbox - since Dovecot v2.0.beta5 -; * sdbox - since Dovecot v2.0.rc3 -format = maildir -; A colon separated list of mailbox names, that should be created (String) -; e.g.: folders = Drafts:Sent:Templates:Trash:Lists.Dovecot:Lists.Postfix -folders = Drafts:Sent:Templates:Trash -; Name of the mailbox root directory in a user's home. (String) -; Usually used names (format: name): -; * maildir: Maildir -; * mdbox: mdbox -; * sdbox: sdbox -root = Maildir -; Set to true if the mailboxes from the folders option should be listed in -; the subscriptions file. (Boolean) -subscribe = true - -# -# Domain settings -# -[domain] -; Should vmm create the postmaster account when a new domain is created? -; (Boolean) -auto_postmaster = true -; Delete domain directory recursive when deleting a domain? (Boolean) -delete_directory = false -; Permissions for domain directories (Int) -; octal 0770 -> decimal 504 -directory_mode = 504 -; Force deletion of accounts and aliases when deleting a domain (Boolean) -force_deletion = false -; -; The service settings will be evaluated and applied when a domain is -; created. The service settings of the domain will be applied when you -; create a new account. -; Use the subcommand domainservices to modify a domain's service settings. -; Or userservices in order to update the service setting of an account. -; Allow smtp by default? (Boolean) -smtp = true -; Allow pop3 by default? (Boolean) -pop3 = true -; Allow imap by default? (Boolean) -imap = true -; Allow managesieve by default? (Boolean) -sieve = true -; -; The quota_* settings will be evaluated and applied when a domain is -; created. The domain's quota_* settings will be applied when an account -; is added to a domain. -; Use the subcommand domainquota to modify a domain's quota limits. -; Or userquota in order to update an account's quota limits. -; Quota limit in bytes. 0 means unlimited (String) -; The value can have one of the suffixes: -; * b: bytes -; * k: kilobytes -; * M: megabytes -; * G: gigabytes -; 1024 is the same as 1024b or 1k -quota_bytes = 0 -; Quota limit in number of messages. 0 means unlimited (Int) -quota_messages = 0 -; -; The transport setting will be evaluated and applied when a domain is -; created. The domain's transport setting will be applied when an account -; is added to a domain. -; Use the subcommand domaintransport to modify the transport of a domain. -; Or usertransport in order to update an account's transport setting. -; -; With Dovecot >= v2.0.0 it's strongly recommended that you use Dovecot's -; lmtp instead of the dovecot-lda. -;transport = lmtp:unix:private/dovecot-lmtp -; default transport for domains and accounts (String) -transport = dovecot: - -# -# Account settings -# -[account] -; Delete the user's home directory recursive when deleting an account? (Boolean) -delete_directory = false -; Permissions for the user's home directory and mail directories (Int) -; octal 0700 -> decimal 448 -directory_mode = 448 -; Display disk usage in account info by default? (Boolean) -disk_usage = false -; Should vmm generate a random password when no password was given for the -; useradd subcommand? (Boolean) -random_password = false -; How many characters to include in the generated passwords? (Int) -password_length = 8 - -# -# external binaries -# -[bin] -; location of dovecotpw (Dovecot v1) or doveadm (Dovecot v2) (String) -dovecotpw = /usr/sbin/dovecotpw -; location of disk usage (String) -du = /usr/bin/du -; location of postconf (String) -postconf = /usr/sbin/postconf - -# -# misc settings -# -[misc] -; The base directory for all domains/accounts (String) -base_directory = /srv/mail -; Number of encryption rounds for the password_scheme BLF-CRYPT (Int) -crypt_blowfish_rounds = 5 -; Number of encryption rounds for the password_scheme SHA256-CRYPT (Int) -crypt_sha256_rounds = 5000 -; Number of encryption rounds for the password_scheme SHA512-CRYPT (Int) -crypt_sha512_rounds = 5000 -; the version number from `dovecot --version` (String) -; e.g. 1.2.17, 2.0.21, 2.1.9 or 2.2.beta1 -dovecot_version = 2.1.9 -; NOTE: When using other password schemes than PLAIN or CRAM-MD5, you -; have to remove `cram-md5' from the auth_mechanisms setting in -; dovecot/conf.d/10-auth.conf. -; Password scheme to use (see also: ´vmm listpwschemes`) (String) -password_scheme = CRAM-MD5 - diff -r 659c4476c57c -r b678a1c43027 doc/web/source/_static/vmm_logo.png Binary file doc/web/source/_static/vmm_logo.png has changed diff -r 659c4476c57c -r b678a1c43027 doc/web/source/conf.py --- a/doc/web/source/conf.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,242 +0,0 @@ -# -*- coding: utf-8 -*- -# -# vmm documentation build configuration file, created by -# sphinx-quickstart on Mon Jul 2 21:23:52 2012. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys, os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.coverage'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'vmm' -copyright = u'2007 - 2014, Pascal Volk' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0.6' -# The full version, including alpha/beta/rc tags. -release = '0.6.2' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = [] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'friendly' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'pyramid' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# "<project> v<release> documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -html_logo = '_static/vmm_logo.png' - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -html_domain_indices = False - -# If false, no index is generated. -html_use_index = False - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -html_show_sphinx = False - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a <link> tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -html_use_opensearch = 'http://vmm.localdomain.org' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'vmmdoc' - - -# -- Options for LaTeX output -------------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'vmm.tex', u'vmm Documentation', - u'Pascal Volk', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'vmm', u'vmm Documentation', - [u'Pascal Volk'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------------ - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'vmm', u'vmm Documentation', - u'Pascal Volk', 'vmm', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' diff -r 659c4476c57c -r b678a1c43027 doc/web/source/download.rst --- a/doc/web/source/download.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -=============== -Downloading vmm -=============== - -Current version ---------------- -|curr_vers_rel_date| -|rel_hist| - -Download a gzip compressed archive ----------------------------------- -vmm could be downloaded from the `download page`_ at `SourceForge`_. To -extract the downloaded archive use ``tar xzf vmm-0.6.2.tar.gz``. This will -create the new directory :file:`vmm-0.6.2` in the current working directory. - -Verify the downloaded archive -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you have downloaded the archive from the download site you can -optionally verify the integrity_ of this archive. -In order to verify the integrity of the archive you have to download the -corresponding signature file (:file:`vmm-0.6.2.tar.gz.sig`) too. -The signature can be verified using GPG_ or PGP_. -For example to check the signature of the archive :file:`vmm-0.6.2.tar.gz` -you can execute this command ``gpg --verify vmm-0.6.2.tar.gz.sig``. - -The tarball was signed by Pascal Volk (ID 0xC51139FE). -Older releases (≦ 0.6.1) were signed with key ID 0xCEC0904E). -You can fetch the public key from a key server using the command -``gpg --recv-keys 0xC51139FE``. - -Get vmm from the Mercurial repository -------------------------------------- -To get a tagged clone of the current vmm release from the Mercurial_ -repository use: -``hg clone http://hg.localdomain.org/vmm/ -r vmm-0.6.2 vmm-0.6.2``. -This will put the files into the new created directory :file:`vmm-0.6.2`. - -When you omit the ``-r vmm-0.6.2`` option, you will get the latest changes -from the `vmm repository`_. This code may work for you or not. - -Get vmm from the Git repository -------------------------------- -The Debian project is hosting the `Git repository of vmm -<http://anonscm.debian.org/gitweb/?p=collab-maint/vmm.git>`_. -The *upstream* branch is a mirror of the Mercurial *default* branch. -The *master* branch is for Debian packaging. -In order to clone the *upstream* branch use: -``git clone --branch upstream git://anonscm.debian.org/collab-maint/vmm.git`` - -Packages --------- -Debian -^^^^^^ -Since Debian Wheezy vmm is also `available <http://packages.debian.org/vmm>`_ -in the Debian package repository. -The vmm package is `maintained <http://packages.qa.debian.org/v/vmm.html>`_ -by Martin F. Krafft. -Take a look at the file :file:`/usr/share/doc/vmm/README.Debian` for Debian -specific modifications. - -.. include:: substitutions.rst -.. include:: ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/ext_references.rst --- a/doc/web/source/ext_references.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -.. External references -.. _AuthDatabase/SQL: http://wiki.dovecot.org/AuthDatabase/SQL -.. _COPYING: http://hg.localdomain.org/vmm/file/tip/COPYING -.. _Client Authentication: \ - http://wiki.postgresql.org/wiki/Client_Authentication -.. _Dovecot wiki: http://wiki2.dovecot.org/ -.. _Dovecot: http://dovecot.org/ -.. _GID: http://en.wikipedia.org/wiki/Group_identifier_%28Unix%29 -.. _GPG: http://en.wikipedia.org/wiki/GNU_Privacy_Guard -.. _IDN: http://en.wikipedia.org/wiki/Internationalized_domain_name -.. _LDA: http://wiki.dovecot.org/LDA -.. _LMTP: http://master.wiki2.dovecot.org/LMTP -.. _Maildir: http://wiki2.dovecot.org/MailboxFormat/Maildir -.. _MainConfig: http://wiki.dovecot.org/MainConfig -.. _Mercurial: http://mercurial.selenic.com/ -.. _PGP: http://en.wikipedia.org/wiki/Pretty_Good_Privacy -.. _Postfix: http://www.postfix.org/ -.. _PostgreSQL: http://www.postgresql.org/ -.. _Psycopg: http://initd.org/psycopg/ -.. _PyCrypto: http://www.pycrypto.org/ -.. _Python: http://www.python.org/ -.. _SourceForge: http://sourceforge.net/ -.. _UID: http://en.wikipedia.org/wiki/User_identifier_%28Unix%29 -.. _Upgrading: http://wiki2.dovecot.org/Upgrading -.. _dbox: http://wiki2.dovecot.org/MailboxFormat/dbox -.. _download page: https://sourceforge.net/projects/vmm/files/ -.. _freenode: http://freenode.net/ -.. _integrity: http://en.wikipedia.org/wiki/Data_integrity -.. _issue tracker: https://bitbucket.org/pvo/vmm/issues -.. _mxDateTime: http://www.egenix.com/products/python/mxBase/mxDateTime/ -.. _mxTools: http://www.egenix.com/products/python/mxBase/mxTools/ -.. _passdb: http://wiki.dovecot.org/PasswordDatabase -.. _pg_dump: http://www.postgresql.org/docs/current/static/app-pgdump.html -.. _pg_hba.conf: \ - http://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html -.. _pgsql_table(5): http://www.postfix.org/pgsql_table.5.html -.. _pipe(8): http://www.postfix.org/pipe.8.html -.. _pyPgSQL: http://pypgsql.sourceforge.net/ -.. _relocated: http://www.postfix.org/relocated.5.html -.. _setuid: http://en.wikipedia.org/wiki/Setuid -.. _transport: http://www.postfix.org/transport.5.html -.. _userdb: http://wiki.dovecot.org/UserDatabase -.. _virtual_alias_expansion_limit: \ - http://www.postfix.org/postconf.5.html#virtual_alias_expansion_limit -.. _vmm repository: http://hg.localdomain.org/vmm/ -.. _vmm-users: http://lists.sourceforge.net/lists/listinfo/vmm-users -.. _vmm: irc://chat.freenode.net/vmm diff -r 659c4476c57c -r b678a1c43027 doc/web/source/features.rst --- a/doc/web/source/features.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -=============== -Features of vmm -=============== - -General features ----------------- - ‣ Unicode/UTF-8 capable (input/storage/output) - ‣ supports IDN_ (also ccTLDs/ccIDNs and 'new' gTLDs) - ‣ supports the mailbox format Maildir_ and Dovecot's own high-performance - mailbox formats single- and multi-\ dbox_ - ‣ configurable basic mailbox structure, including sub-mailboxes - ‣ multilingual — currently: - - * Dutch - * English - * Finnish - * French - * German - * Vietnamese - -Domain features ---------------- - ‣ configurable transport_ setting per domain - ‣ unique group identifier (GID) per domain - ‣ each domain may have one or more alias domain names - ‣ activate or deactivate services (SMTP, POP3, IMAP and ManageSieve) for new - or all accounts of a domain - ‣ configurable quota limits (size and/or number of messages) for the - domain's accounts - ‣ supports relocated_ users - ‣ the postmaster account can be created automatically when a new domain is - created - ‣ supports per-domain catch-all aliases - -Alias domain features ---------------------- - ‣ alias domain names can be switched between domains - -Account features ----------------- - ‣ configurable transport per account - ‣ activate or deactivate one/more/all services (SMTP, POP3, IMAP and - ManageSieve) per account - ‣ configurable quota limit (size and/or number of messages) per user - ‣ per-account configuration overrides defaults defined by the domain, - otherwise the setting is inherited - ‣ unique user identifier (UID) per user - -Alias features --------------- - ‣ supports multiple destinations per e-mail alias - ‣ destinations can be deleted separately - ‣ respects Postfix' virtual_alias_expansion_limit_ on creation - ‣ destinations can be interpolated using the original address' local-part - and domain, allowing aliases to have different meaning in alias domains, - e.g. with the following defined in example.org:: - - postmaster@example.org → postmaster+%d@admin.example.org - - If example.com is an alias domain of example.org, the alias will become:: - - postmaster@example.org → postmaster+example.org@admin.example.org - postmaster@example.com → postmaster+example.com@admin.example.org - -Wanted features ---------------- - ‣ Do you want more? Please use the `issue tracker`_ to submit your proposal. - -.. include:: ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/howto.rst --- a/doc/web/source/howto.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -========= -Using vmm -========= - -vmm is the easy to use command-line tool of the Virtual Mail Manager. -It allows you to simply and quickly administer your mail server. -The general command syntax looks like:: - - vmm subcommand [argument …] - -Each subcommand has both a long and a short form. -Both forms are case sensitive. -The subcommands are categorized by their functionality: - -.. toctree:: - :maxdepth: 1 - - howto/general_subcommands - howto/manage_domains - howto/manage_alias_domains - howto/manage_accounts - howto/manage_alias_addresses - howto/manage_catch-all_addresses - howto/manage_relocated_users - - -Most of the *subcommand*\ s take one or more *argument*\ s. - -Arguments ---------- -address - The complete e-mail address (*local-part*\ @\ *fqdn*) of an user account, - alias address or relocated user. - -destination - Is either an e-mail address when used with - :doc:`Alias subcommands <howto/manage_alias_addresses>`. - Or a *fqnd* when used with - :doc:`Alias domain subcommands <howto/manage_alias_domains>`. - -fqdn - The fully qualified domain name – without the trailing dot – of a domain - or alias domain. - -messages - An integer value which specifies a quota limit in number of messages. - **0** (zero) means unlimited - no quota limit for the number of messages. - -option - Is the name of a configuration option, prefixed with the section name and - a dot. - For example: *misc*\ **.**\ *transport* - All configuration options are described in :manpage:`vmm.cfg(5)`. - -service - The name of a service, commonly used with Dovecot. - Supported services are: **imap**, **pop3**, **sieve** and **smtp**. - -storage - Specifies a quota limit in bytes. - One of the following prefixes can be appended to the integer value: - **b** (bytes), **k** (kilobytes), **M** (megabytes) or **G** (gigabytes). - **0** (zero) means unlimited - no quota limit in bytes. - -transport - A transport for Postfix, written as: *transport*\ **:** or - *transport*\ **:**\ *nexthop*. - See :manpage:`transport(5)` for more details. - -Files ------ -:command:`vmm` reads its configuration data from :file:`vmm.cfg`. - -:file:`/root/vmm.cfg` - will be used when found. - -:file:`/usr/local/etc/vmm.cfg` - will be used when the above file doesn't exist. - -:file:`/etc/vmm.cfg` - will be used when none of the both above mentioned files exists. diff -r 659c4476c57c -r b678a1c43027 doc/web/source/howto/general_subcommands.rst --- a/doc/web/source/howto/general_subcommands.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,302 +0,0 @@ -=================== -General subcommands -=================== - -configget ---------- -Syntax: - | **vmm configget** *option* - | **vmm cg** *option* - -This subcommand is used to display the actual value of the given -configuration *option*. - -Example: - -.. code-block:: console - - root@host:~# vmm configget misc.crypt_sha512_rounds - misc.crypt_sha512_rounds = 5000 - -.. versionadded:: 0.6.0 - -configset ---------- -Syntax: - | **vmm configset** *option value* - | **vmm cs** *option value* - -Use this subcommand to set or update a single configuration option's value. -*option* is the configuration option, *value* is the *option*'s new value. - -.. note:: - This subcommand will create a new :file:`vmm.cfg` without any comments. - Your current configuration file will be backed as :file:`vmm.cfg.bak`. - -Example: - -.. code-block:: console - - root@host:~# vmm configget domain.transport - domain.transport = dovecot: - root@host:~# vmm configset domain.transport lmtp:unix:private/dovecot-lmtp - root@host:~# vmm cg domain.transport - domain.transport = lmtp:unix:private/dovecot-lmtp - -.. versionadded:: 0.6.0 - -configure ---------- -Syntax: - | **vmm configure** [*section*] - | **vmm cf** [*section*] - -Starts the interactive configuration for all configuration sections. - -In this process the currently set value of each option will be displayed -in square brackets. -If no value is configured, the default value of each option will be -displayed in square brackets. -Press the return key, to accept the displayed value. - -If the optional argument *section* is given, only the configuration options -from the given section will be displayed and will be configurable. -The following sections are available: - -======== ========================== -section description -======== ========================== -account Account settings -bin Paths to external binaries -database Database settings -domain Domain settings -mailbox Mailbox settings -misc Miscellaneous settings -======== ========================== - -All configuration options are described in :manpage:`vmm.cfg(5)`. - -.. note:: - This subcommand will create a new :file:`vmm.cfg` without any comments. - Your current configuration file will be backed as :file:`vmm.cfg.bak`. - -Example: - -.. code-block:: console - - root@host:~# vmm configure mailbox - Using configuration file: /usr/local/etc/vmm.cfg - - * Configuration section: `mailbox' - Enter new value for option folders [Drafts:Sent:Templates:Trash]: - Enter new value for option format [maildir]: mdbox - Enter new value for option subscribe [True]: - Enter new value for option root [Maildir]: mdbox - -getuser -------- -Syntax: - | **vmm getuser** *uid* - | **vmm gu** *ui* - -If only the *uid* is available, for example from process list, the -subcommand **getuser** will show the user's address. - -Example: - -.. code-block:: console - - root@host:~# vmm getuser 79876 - Account information - ------------------- - UID............: 79876 - GID............: 70704 - Address........: a.user@example.com - -help ----- -Syntax: - | **vmm help** [*subcommand*] - | **vmm h** [*subcommand*] - -Prints a list of available subcommands with a short description to stdout. -When a *subcommand* was given, help for that *subcommand* will be displayed. -After this :command:`vmm` exits. - -listaddresses -------------- -Syntax: - | **vmm listaddresses** [*pattern*] - | **vmm ll** [*pattern*] - -This command lists all defined addresses. Addresses belonging to -alias-domains are prefixed with a '-', addresses of regular domains with -a '+'. -Additionally, the letters 'u', 'a', and 'r' indicate the type of each -address: user, alias and relocated respectively. The output can be limited -with an optional *pattern*. - -To perform a wild card search, the **%** character can be used at the start -and/or the end of the *pattern*. - -Example: - -.. code-block:: console - - root@host:~# vmm ll example.com - Matching addresses - ------------------ - [u+] a.user@example.com - [r+] b.user@example.com - [u+] d.user@example.com - [u+] john.doe@example.com - [u+] postmaster@example.com - [a+] support@example.com - -.. versionadded:: 0.6.0 - -listaliases ------------ -Syntax: - | **vmm listaliases** [*pattern*] - | **vmm la** [*pattern*] - -This command lists all defined aliases. Aliases belonging to alias-domains -are prefixed with a '-', addresses of regular domains with a '+'. -The output can be limited with an optional *pattern*. - -To perform a wild card search, the **%** character can be used at the start -and/or the end of the *pattern*. - -Example: - -.. code-block:: console - - root@host:~# vmm listaliases example.com - Matching aliases - ---------------- - [+] support@example.com - -.. versionadded:: 0.6.0 - -listdomains ------------ -Syntax: - | **vmm listdomains** [*pattern*] - | **vmm ld** [*pattern*] - -This subcommand lists all available domains. -All domain names will be prefixed either with '[+]', if the domain is -a primary domain, or with '[-]', if it is an alias domain name. -The output can be limited with an optional pattern. - -To perform a wild card search, the **%** character can be used at the start -and/or the end of the *pattern*. - -Example: - -.. code-block:: console - - root@host:~# vmm listdomains %example% - Matching domains - ---------------- - [+] example.com - [-] e.g.example.com - [-] example.name - [+] example.net - [+] example.org - -listpwschemes -------------- -Syntax: - | **vmm listpwschemes** - | **vmm lp** - -This subcommand lists all password schemes which could be used in the -:file:`vmm.cfg` as value of the *misc.password_scheme* option. -The output varies, depending on the used Dovecot version and the system's -libc. - -When your Dovecot installation isn't too old, you will see additionally -a few usable encoding suffixes. -One of them can be appended to the password scheme. - -Example: - -.. code-block:: console - - root@host:~# vmm listpwschemes - Usable password schemes - ----------------------- - CRYPT SHA512-CRYPT LDAP-MD5 DIGEST-MD5 SHA256 SHA512 SSHA512 - SKEY SSHA NTLM RPA MD5-CRYPT HMAC-MD5 SHA1 PLAIN SHA CRAM-MD5 - SSHA256 MD5 LANMAN CLEARTEXT PLAIN-MD5 PLAIN-MD4 OTP SMD5 - SHA256-CRYPT - - Usable encoding suffixes - ------------------------ - .B64 .BASE64 .HEX - -.. versionadded:: 0.6.0 - -listrelocated -------------- -Syntax: - | **vmm listrelocated** [*pattern*] - | **vmm lr** [*pattern*] - -This command lists all defined relocated addresses. -Relocated entries belonging to alias-domains are prefixed with a '-', -addresses of regular domains with a '+'. -The output can be limited with an optional *pattern*. - -To perform a wild card search, the **%** character can be used at the start -and/or the end of the *pattern*. - -Example: - -.. code-block:: console - - root@host:~# vmm listrelocated example.com - Matching relocated users - ------------------------ - [+] b.user@example.com - -.. versionadded:: 0.6.0 - -listusers ---------- -Syntax: - | **vmm listusers** [*pattern*] - | **vmm lu** [*pattern*] - -This command lists all user accounts. -User accounts belonging to alias-domains are prefixed with a '-', addresses -of regular domains with a '+'. -The output can be limited with an optional *pattern*. - -To perform a wild card search, the **%** character can be used at the start -and/or the end of the *pattern*. - -Example: - -.. code-block:: console - - root@host:~# vmm listusers example.com - Matching user accounts - ---------------------- - [+] a.user@example.com - [+] d.user@example.com - [+] john.doe@example.com - [+] postmaster@example.com - -.. versionadded:: 0.6.0 - -version -------- -Syntax: - | **vmm version** - | **vmm v** - -Prints :command:`vmm`'s version and copyright information to stdout. -After this :command:`vmm` exits. diff -r 659c4476c57c -r b678a1c43027 doc/web/source/howto/manage_accounts.rst --- a/doc/web/source/howto/manage_accounts.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -================= -Managing accounts -================= -useradd -------- -Syntax: - | **vmm useradd** *address* [*password*] - | **vmm ua** *address* [*password*] - -Use this subcommand to create a new e-mail account for the given *address*. - -If the password is not provided, :command:`vmm` will prompt for it -interactively. -When no *password* is provided and *account.random_password* is set to -**true**, :command:`vmm` will generate a random password and print it to -stdout after the account has been created. - -Example: - -.. code-block:: console - - root@host:~# vmm ua d.user@example.com "A 5ecR3t P4s5\/\/0rd" - root@host:~# vmm useradd e.user@example.com - Enter new password: - Retype new password: - -userdelete ----------- -Syntax: - | **vmm userdelete** *address* [*force*] - | **vmm ud** *address* [*force*] - -Use this subcommand to delete the account with the given *address*. - -If there are one or more aliases with an identical destination address, -:command:`vmm` will abort the requested operation and show an error message. -To prevent this, specify the optional keyword **force**. - -userinfo --------- -Syntax: - | **vmm userinfo** *address* [*details*] - | **vmm ui** *address* [*details*] - -This subcommand displays some information about the account specified by -*address*. - -If the optional argument *details* is given some more information will be -displayed. -Possible values for *details* are: - -======= ============================================================== -value description -======= ============================================================== -aliases to list all alias addresses with the destination *address* -du to display the disk usage of the user's mail directory. - In order to summarize the disk usage each time this subcommand - is executed automatically, set *account.disk_usage* in your - :file:`vmm.cfg` to **true**. -full to list all information mentioned above -======= ============================================================== - -Example: - -.. code-block:: console - - root@host:~# vmm ui d.user@example.com - Account information - ------------------- - Address..........: d.user@example.com - Name.............: None - UID..............: 79881 - GID..............: 70704 - Home.............: /srv/mail/2/70704/79881 - Mail_Location....: mdbox:~/mdbox - Quota Storage....: [ 0.00%] 0/500.00 MiB [domain default] - Quota Messages...: [ 0.00%] 0/10,000 [domain default] - Transport........: lmtp:unix:private/dovecot-lmtp [domain default] - SMTP.............: disabled [domain default] - POP3.............: disabled [domain default] - IMAP.............: enabled [domain default] - SIEVE............: enabled [domain default] - -username --------- -Syntax: - | **vmm username** *address* [*name*] - | **vmm un** *address* [*name*] - -The user's real *name* can be set/updated with this subcommand. - -If no *name* is given, the value stored for the account is erased. - -Example: - -.. code-block:: console - - root@host:~# vmm un d.user@example.com "John Doe" - -usernote --------- -Syntax: - | **vmm usernote** *address* [*note*] - | **vmm uo** *address* [*note*] - -With this subcommand, it is possible to attach a note to the specified -account. -Without an argument, an existing note is removed. - -Example: - -.. code-block:: console - - root@host:~# vmm uo d.user@example.com Only needed until end of May 2012 - -.. versionadded:: 0.6.0 - -userpassword ------------- -Syntax: - | **vmm userpassword** *address* [*password*] - | **vmm up** *address* [*password*] - -The password of an account can be updated with this subcommand. - -If no *password* was provided, :command:`vmm` will prompt for it interactively. - -Example: - -.. code-block:: console - - root@host:~# vmm up d.user@example.com "A |\/|0r3 5ecur3 P4s5\/\/0rd?" - -userquota ---------- -Syntax: - | **vmm userquota** *address storage* [*messages*] - | **vmm uq** *address storage* [*messages*] - -This subcommand is used to set a new quota limit for the given account. - -When the argument *messages* was omitted the default number of messages -**0** (zero) will be applied. - -Instead of *storage* pass **domain** to remove the account-specific -override, causing the domain's value to be in effect. - -Example: - -.. code-block:: console - - root@host:~# userquota d.user@example.com 750m - -.. versionadded:: 0.6.0 - -userservices ------------- -Syntax: - | **vmm userservices** *address* [*service ...*] - | **vmm us** *address* [*service ...*] - -To grant a user access to the specified services, use this command. - -All omitted services will be deactivated/unusable for the user with the -given *address*. - -Instead of *service* pass **domain** to remove the account-specific override, -causing the domain's value to be in effect. - -Example: - -.. code-block:: console - - root@host:~# userservices d.user@example.com SMTP IMAP - -.. _usertransport: - -usertransport -------------- -Syntax: - | **vmm usertransport** *address transport* - | **vmm ut** *address transport* - -A different *transport* for an account can be specified with this subcommand. - -Instead of *transport* pass **domain** to remove the account-specific -override, causing the domain's value to be in effect. - -Example: - -.. code-block:: console - - root@host:~# ut c.user@example.com smtp:[pc105.it.example.com] diff -r 659c4476c57c -r b678a1c43027 doc/web/source/howto/manage_alias_addresses.rst --- a/doc/web/source/howto/manage_alias_addresses.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,65 +0,0 @@ -======================== -Managing alias addresses -======================== -aliasadd --------- -Syntax: - | **vmm aliasadd** *address destination ...* - | **vmm aa** *address destination ...* - -This subcommand is used to create a new alias *address* with one or more -*destination* addresses. - -Within the destination address, the placeholders **%n**, **%d**, and **%=** -will be replaced by the local-part, the domain, or the email address with -**@** replaced by **=** respectively. -In combination with alias domains, this enables domain-specific destinations. - -Example: - -.. code-block:: console - - root@host:~# vmm aliasadd john.doe@example.com d.user@example.com - root@host:~# vmm aa support@example.com d.user@example.com e.user@example.com - root@host:~# vmm aa postmaster@example.com postmaster+%d@example.org - -aliasdelete ------------ -Syntax: - | **vmm aliasdelete** *address* [*destination* ...] - | **vmm ad** *address* [*destination* ...] - -This subcommand is used to delete one or multiple *destination*\ s from the -alias with the given *address*. - -When no *destination* address was specified the alias with all its -destinations will be deleted. - -Example: - -.. code-block:: console - - root@host:~# vmm ad support@example.com d.user@example.com - -.. versionchanged:: 0.6.1 - Accept multiple destinations. - -aliasinfo ---------- -Syntax: - | **vmm aliasinfo** *address* - | **vmm ai** *address* - -Information about the alias with the given *address* can be displayed with -this subcommand. - -Example: - -.. code-block:: console - - root@host:~# vmm aliasinfo support@example.com - Alias information - ----------------- - Mail for support@example.com will be redirected to: - * e.user@example.com - diff -r 659c4476c57c -r b678a1c43027 doc/web/source/howto/manage_alias_domains.rst --- a/doc/web/source/howto/manage_alias_domains.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -====================== -Managing alias domains -====================== -An alias domain is an alias for a domain that was previously added with the -subcommand :ref:`domainadd`. -All accounts, aliases and relocated users from the domain will be also -available in the alias domain. -In the following is to be assumed that example.net is an alias for example.com. - -Postfix will not accept erroneously e-mails for unknown.user\@example.net -and bounce them back later to the mostly faked sender. -Postfix will immediately reject all e-mails addressed to nonexistent users. - -This behavior is ensured as long as you use the recommended database queries -in your :file:`{$config_directory}/pgsql-*.cf` configuration files. - -aliasdomainadd --------------- -Syntax: - | **vmm aliasdomainadd** *fqdn destination* - | **vmm ada** *fqdn destination* - -This subcommand adds the new alias domain (*fqdn*) to the *destination* -domain that should be aliased. - -Example: - -.. code-block:: console - - root@host:~# vmm aliasdomainadd example.net example.com - -aliasdomaindelete ------------------ -Syntax: - | **vmm aliasdomaindelete** *fqdn* - | **vmm add** *fqdn* - -Use this subcommand if the alias domain *fqdn* should be removed. - -Example: - -.. code-block:: console - - root@host:~# vmm aliasdomaindelete e.g.example.com - -aliasdomaininfo ---------------- -Syntax: - | **vmm aliasdomaininfo** *fqdn* - | **vmm adi** *fqdn* - -This subcommand shows to which domain the alias domain *fqdn* is assigned to. - -Example: - -.. code-block:: console - - root@host:~# vmm adi example.net - Alias domain information - ------------------------ - The alias domain example.net belongs to: - * example.com - -aliasdomainswitch ------------------ -Syntax: - | **vmm aliasdomainswitch** *fqdn destination* - | **vmm aos** *fqdn destination* - -If the destination of the existing alias domain *fqdn* should be switched -to another *destination* use this subcommand. - -Example: - -.. code-block:: console - - root@host:~# vmm aliasdomainswitch example.name example.org diff -r 659c4476c57c -r b678a1c43027 doc/web/source/howto/manage_catch-all_addresses.rst --- a/doc/web/source/howto/manage_catch-all_addresses.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -============================ -Managing catch-all addresses -============================ -catchalladd ------------ -Syntax: - | **vmm catchalladd** *fqdn destination ...* - | **vmm caa** *fqdn destination ...* - -This subcommand allows to specify destination addresses for a domain, which -shall receive mail addressed to unknown local-parts within that domain. -Those catch-all aliases hence "catch all" mail to any address in the domain -(unless a more specific alias, mailbox or relocated entry exists). - -.. warning:: - Catch-all addresses can cause mail server flooding because spammers like - to deliver mail to all possible combinations of names, e.g. to all - addresses between abba\@example.org and zztop\@example.org. - -Example: - -.. code-block:: console - - root@host:~# vmm catchalladd example.com user@example.org - -.. versionadded:: 0.6.0 - -catchalldelete --------------- -Syntax: - | **vmm catchalldelete** *fqdn* [*destination* ...] - | **vmm cad** *fqdn* [*destination* ...] - -With this subcommand, catch-all aliases defined for a domain can be removed, -either all of them, or those *destination*\ s which were specified explicitly. - -Example: - -.. code-block:: console - - root@host:~# vmm catchalldelete example.com user@example.com - -.. versionadded:: 0.6.0 - -.. versionchanged:: 0.6.1 - Accept multiple destinations. - -catchallinfo ------------- -Syntax: - | **vmm catchallinfo** *fqdn* - | **vmm cai** *fqdn* - -This subcommand displays information about catch-all aliases defined for -a domain. - -Example: - -.. code-block:: console - - root@host:~# vmm catchallinfo example.com - Catch-all information - --------------------- - Mail to unknown localparts in domain example.com will be sent to: - * user@example.org - -.. versionadded:: 0.6.0 - diff -r 659c4476c57c -r b678a1c43027 doc/web/source/howto/manage_domains.rst --- a/doc/web/source/howto/manage_domains.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -================ -Managing domains -================ -.. _domainadd: - -domainadd ---------- -Syntax: - | **vmm domainadd** *fqdn* [*transport*] - | **vmm da** *fqdn* [*transport*] - -Adds the new domain into the database and creates the domain directory. - -If the optional argument transport is given, it will override the default -transport (*domain.transport*) from :file:`vmm.cfg`. -The specified *transport* will be the default transport for all new accounts -in this domain. - -Configuration-related behavior: - - *domain.auto_postmaster* - When that option is set to **true** (default) :command:`vmm` will - automatically create the postmaster account for the new domain and prompt - for **postmaster**\ @\ *fqdn*'s password. - - *account.random_password* - When the value of that option is also set to **true**, :command:`vmm` - will automatically create the postmaster account for the new domain and - print the generated postmaster password to stdout. - -Example: - -.. code-block:: console - - root@host:~# vmm domainadd support.example.com smtp:[mx1.example.com]:2025 - Creating account for postmaster@support.example.com - Enter new password: - Retype new password: - root@host:~# vmm cs account.random_password true - root@host:~# vmm da sales.example.com - Creating account for postmaster@sales.example.com - Generated password: pLJUQ6Xg_z - -domaindelete ------------- -Syntax: - | **vmm domaindelete** *fqdn* [**force**] - | **vmm dd** *fqdn* [**force**] - -This subcommand deletes the domain specified by *fqdn*. - -If there are accounts, aliases and/or relocated users assigned to the given -domain, :command:`vmm` will abort the requested operation and show an error -message. -If you know, what you are doing, you can specify the optional keyword -**force**. - -If you really always know what you are doing, edit your :file:`vmm.cfg` and -set the option *domain.force_deletion* to **true**. - -domaininfo ----------- -Syntax: - | **vmm domaininfo** *fqdn* [*details*] - | **vmm di** *fqdn* [*details*] - -This subcommand shows some information about the given domain. - -For a more detailed information about the domain the optional argument -*details* can be specified. -A possible *details* value can be one of the following six keywords: - -============ ========================================================== -keyword description -============ ========================================================== -accounts to list the e-mail addresses of all existing user accounts -aliasdomains to list all assigned alias domain names -aliases to list all available alias e-mail addresses -catchall to list all catch-all destinations -relocated to list the e-mail addresses of all relocated users -full to list all information mentioned above -============ ========================================================== - -Example: - -.. code-block:: console - - root@host:~# vmm domaininfo sales.example.com - Domain information - ------------------ - Domain Name......: sales.example.com - GID..............: 70708 - Domain Directory.: /srv/mail/c/70708 - Quota Limit/User.: Storage: 500.00 MiB; Messages: 10,000 - Active Services..: IMAP SIEVE - Transport........: lmtp:unix:private/dovecot-lmtp - Alias Domains....: 0 - Accounts.........: 1 - Aliases..........: 0 - Relocated........: 0 - Catch-All Dests..: 0 - -domainnote ----------- -Syntax: - | **vmm domainnote** *fqdn* [*note*] - | **vmm do** *fqdn* [*note*] - -With this subcommand, it is possible to attach a note to the specified -domain. -Without an argument, an existing note is removed. - -Example: - -.. code-block:: console - - root@host:~# vmm do example.com Belongs to Robert - -.. versionadded:: 0.6.0 - -domainquota ------------ -Syntax: - | **vmm domainquota** *fqdn storage* [*messages*] [**force**] - | **vmm dq** *fqdn storage* [*messages*] [**force**] - -This subcommand is used to configure a new quota limit for the accounts -of the domain - not for the domain itself. - -The default quota limit for accounts is defined in the :file:`vmm.cfg` -(*domain.quota_bytes* and *domain.quota_messages*). - -The new quota limit will affect only those accounts for which the limit has -not been overridden. -If you want to restore the default to all accounts, you may pass the keyword -**force**. -When the argument *messages* was omitted the default number of messages -**0** (zero) will be applied. - -Example: - -.. code-block:: console - - root@host:~# vmm domainquota example.com 1g force - -.. versionadded:: 0.6.0 - -domainservices --------------- -Syntax: - | **vmm domainservices** *fqdn* [*service ...*] [**force**] - | **vmm ds** *fqdn* [*service ...*] [**force**] - -To define which services could be used by the users of the domain — with -the given *fqdn* — use this subcommand. - -Each specified *service* will be enabled/usable. -All other services will be deactivated/unusable. -Possible service names are: **imap**, **pop3**, **sieve** and **smtp**. -The new service set will affect only those accounts for which the set has -not been overridden. -If you want to restore the default to all accounts, you may pass the -keyword **force**. - -.. versionadded:: 0.6.0 - -.. _domaintransport: - -domaintransport ---------------- -Syntax: - | **vmm domaintransport** *fqdn transport* [**force**] - | **vmm dt** *fqdn transport* [**force**] - -A new transport for the indicated domain can be set with this subcommand. - -The new transport will affect only those accounts for which the transport -has not been overridden. -If you want to restore the default to all accounts, you may pass the -keyword **force**. - -Example: - -.. code-block:: console - - root@host:~# vmm domaintransport support.example.com dovecot: diff -r 659c4476c57c -r b678a1c43027 doc/web/source/howto/manage_relocated_users.rst --- a/doc/web/source/howto/manage_relocated_users.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -======================== -Managing relocated users -======================== -relocatedadd ------------- -Syntax: - | **vmm relocatedadd** *address newaddress* - | **vmm ra** *address newaddress* - -A new relocated user can be created with this subcommand. - -*address* is the user's ex-email address, for example b.user\@example.com, -and *newaddress* points to the new email address where the user can be -reached. - -Example: - -.. code-block:: console - - root@host:~# vmm relocatedadd b.user@example.com b-user@company.tld - -relocateddelete ---------------- -Syntax: - | **vmm relocateddelete** *address* - | **vmm rd** *address* - -Use this subcommand in order to delete the relocated user with the given -*address*. - -Example: - -.. code-block:: console - - root@host:~# vmm relocateddelete b.user@example.com - -relocatedinfo -------------- -Syntax: - | **vmm relocatedinfo** *address* - | **vmm ri** *address* - -This subcommand shows the new address of the relocated user with the given -*address*. - -Example: - -.. code-block:: console - - root@host:~# vmm relocatedinfo b.user@example.com - Relocated information - --------------------- - User 'b.user@example.com' has moved to 'b-user@company.tld' diff -r 659c4476c57c -r b678a1c43027 doc/web/source/index.rst --- a/doc/web/source/index.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -============================ -vmm - a virtual mail manager -============================ -**vmm** is the easy to use and configurable command line tool for -administrators and postmasters, to manage domains, alias-domains, accounts -and relocated mail users. See the :doc:`features` page for more details. -It allows the fast and easy management of mail servers. - -vmm is written in Python_. It's designed for installations using Dovecot_ -and Postfix_ with a PostgreSQL_ backend. vmm should work on each -Linux/UNIX-like operation system. - -Current version ---------------- -|curr_vers_rel_date| -|rel_hist| - -Contacts --------- -There's the vmm-users_ mailing list for general vmm discussion. There's -also the #\ vmm_ IRC channel on the freenode_ network. -Please use the `issue tracker`_ to report any kind of bugs. - -License -------- -In short: "**New BSD License**" aka "3-clause license". For a few more -details see the COPYING_ file. - -Contents --------- - -.. toctree:: - :maxdepth: 1 - - features - download - install - upgrade - howto - -* :ref:`search` - -.. include:: substitutions.rst -.. include:: ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/install.rst --- a/doc/web/source/install.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -============ -Installation -============ - -.. toctree:: - :maxdepth: 1 - - installation/prerequisites - installation/system_preparation - installation/postgresql_configuration - installation/dovecot_configuration - installation/postfix_configuration - installation/install_vmm diff -r 659c4476c57c -r b678a1c43027 doc/web/source/installation/dovecot_configuration.rst --- a/doc/web/source/installation/dovecot_configuration.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,344 +0,0 @@ -===================== -Dovecot configuration -===================== -This page describes in short how to configure Dovecot. - -If you are upgrading your Dovecot installation from v1.\ **1**.x to -v1.\ **2**.x or v\ **1**.x to v\ **2**.x, you should also read Upgrading_ -in the `Dovecot wiki`_. - -Dovecot v1.x ------------- -This setup uses two configuration files. -:file:`dovecot.conf`, the MainConfig_ of the Dovecot server and -:file:`dovecot-sql.conf`, containing the settings for passdb_ and userdb_ -lookups. -For more details see also `AuthDatabase/SQL`_ in the Dovecot wiki. - -dovecot.conf -^^^^^^^^^^^^ -The following configuration example can be used as complete configuration -file. You can also adjust your existing settings. -Use :command:`dovecot -n | head -n 1` to locate your :file:`dovecot.conf`. - -.. note:: Please modify the `postmaster_address` to meet your specific needs. - -.. code-block:: text - :emphasize-lines: 7 - - # all your other settings - #disable_plaintext_auth = no - mail_location = maildir:~/Maildir - first_valid_uid = 70000 - first_valid_gid = 70000 - protocol lda { - postmaster_address = postmaster@YOUR-DOMAIN.TLD - # uncomment this to use server side filtering (Dovecot v1.0.x/v1.1.x) - #mail_plugins = cmusieve - # uncomment this to use server side filtering (Dovecot v1.2.x) - #mail_plugins = sieve - } - protocol pop3 { - pop3_uidl_format = %08Xu%08Xv - } - # uncomment this to use the ManageSieve protocol, if supported by your installation - #protocol managesieve { - # # only valid with Dovecot v1.0.x/v1.1.x. - # # see also: http://wiki.dovecot.org/ManageSieve/Configuration#v1.0.2BAC8-v1.1 - # sieve = ~/.dovecot.sieve - # sieve_storage = ~/sieve - #} - auth default { - mechanisms = cram-md5 login plain - passdb sql { - args = /etc/dovecot/dovecot-sql.conf - } - userdb sql { - args = /etc/dovecot/dovecot-sql.conf - } - user = doveauth - socket listen { - master { - path = /var/run/dovecot/auth-master - mode = 0600 - } - client { - path = /var/spool/postfix/private/dovecot-auth - mode = 0660 - user = postfix - group = postfix - } - } - } - # uncomment this if you use the ManageSieve protocol with Dovecot v1.2.x - #plugin { - # # Sieve and ManageSieve settings - # # see also: http://wiki.dovecot.org/ManageSieve/Configuration#v1.2 - # sieve = ~/.dovecot.sieve - # sieve_dir = ~/sieve - #} - - -.. _dovecot-sql-conf: - -dovecot-sql.conf -^^^^^^^^^^^^^^^^ -This lines contains all information that are required by Dovecot to access -the database and to do the lookups in passdb and userdb. - -.. code-block:: text - - driver = pgsql - connect = host=localhost dbname=mailsys user=dovecot password=$Dovecot_PASS - default_pass_scheme = CRAM-MD5 - password_query = SELECT userid AS "user", password FROM dovecotpassword('%Ln', '%Ld') WHERE %Ls - user_query = SELECT home, uid, gid, mail FROM dovecotuser('%Ln', '%Ld') - -Dovecot v2.x ------------- -Beginning with Dovecot version 2.0 the configuration was split into multiple -files. -It isn't required to use multiple configuration files. -:file:`dovecot.conf` is still the most important configuration file. -Use the command :command:`doveconf -n | head -n 1` to locate your -:file:`dovecot.conf`. -You could put all settings in your :file:`dovecot.conf`. -You can also include multiple files into your :file:`dovecot.conf`. - -I personally prefer it to comment out most of the :file:`dovecot.conf` -and include only my :file:`local.conf`, which contains all the necessary -settings. -You can download my :download:`local.conf <../_static/local.conf>` and use -it in your setup. - -If you want to use multiple configuration files, you have to apply the -following settings to the configuration files mentioned down below. -Everything that isn't mentioned, was commented out. - -.. _dovecot2.conf: - -dovecot.conf -^^^^^^^^^^^^ -.. code-block:: text - - protocols = imap lmtp - # uncomment if your users should be able to manage their sieve scripts - #protocols = imap lmtp sieve - - # uncomment if you want to use the quota plugin - #dict { - # quota = pgsql:/usr/local/etc/dovecot/dovecot-dict-sql.conf.ext - #} - -See also :ref:`dovecot-dict-sql-conf-ext` below. - -.. warning:: Adjust the paths of the :file:`dovecot-dict-sql.conf.ext` - (above) and :file:`dovecot-sql.conf.ext` (below) files to suit your needs. - - -.. _conf-d-10-auth-conf: - -conf.d/10-auth.conf -^^^^^^^^^^^^^^^^^^^ -.. code-block:: text - - auth_mechanisms = plain login cram-md5 - passdb { - driver = sql - args = /usr/local/etc/dovecot/dovecot-sql.conf.ext - } - userdb { - driver = sql - args = /usr/local/etc/dovecot/dovecot-sql.conf.ext - } - #!include auth-system.conf.ext - -See also :ref:`dovecot-sql-conf-ext` below. - - -conf.d/10-mail.conf -^^^^^^^^^^^^^^^^^^^ -.. code-block:: text - - first_valid_gid = 70000 - first_valid_uid = 70000 - mail_access_groups = dovemail - mail_location = maildir:~/Maildir - - # uncomment if you want to use the quota plugin - #mail_plugins = quota - -.. _conf-d-10-master.conf: - -conf.d/10-master.conf -^^^^^^^^^^^^^^^^^^^^^ -.. code-block:: text - - # if you don't want to use secure imap, you have to disable the imaps listener - ##service imap-login { - ## inet_listener imaps { - ## port = 0 - ## } - ##} - - service lmtp { - unix_listener /var/spool/postfix/private/dovecot-lmtp { - user = postfix - group = postfix - mode = 0600 - } - } - - service auth { - user = doveauth - unix_listener auth-userdb { - } - unix_listener /var/spool/postfix/private/dovecot-auth { - user = postfix - group = postfix - mode = 0600 - } - } - - service auth-worker { - unix_listener auth-worker { - user = doveauth - group = $default_internal_user - mode = 0660 - } - user = doveauth - } - - service dict { - unix_listener dict { - group = dovemail - mode = 0660 - } - } - -conf.d/10-ssl.conf -^^^^^^^^^^^^^^^^^^ -.. code-block:: text - - # SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt> - #ssl = yes - - ssl_cert = </etc/ssl/certs/dovecot.pem - ssl_key = </etc/ssl/private/dovecot.pem - - # if you want to disable SSL/TLS, you have set 'ssl = no' and disable the - # imaps listener in conf.d/10-master.conf - -conf.d/15-lda.conf -^^^^^^^^^^^^^^^^^^ -.. note:: Please modify the `postmaster_address` to meet your specific needs. - -.. code-block:: text - :emphasize-lines: 1 - - postmaster_address = postmaster@YOUR-DOMAIN.TLD - recipient_delimiter = + - protocol lda { - # uncomment if you want to use the quota plugin - #mail_plugins = $mail_plugins - # uncomment if you want to use the quota and sieve plugins - #mail_plugins = $mail_plugins sieve - } - -conf.d/20-imap.conf -^^^^^^^^^^^^^^^^^^^ -.. code-block:: text - - protocol imap { - # uncomment if you want to use the quota plugin - #mail_plugins = $mail_plugins imap_quota - } - -conf.d/20-lmtp.conf -^^^^^^^^^^^^^^^^^^^ -.. code-block:: text - - protocol lmtp { - # uncomment if you want to use the quota plugin - #mail_plugins = $mail_plugins - # uncomment if you want to use the quota and sieve plugins - #mail_plugins = $mail_plugins sieve - } - -conf.d/90-quota.conf -^^^^^^^^^^^^^^^^^^^^ -.. code-block:: text - - # uncomment if you want to use the quota plugin - #plugin { - # quota = dict:user:%{uid}:proxy::quota - # quota_rule = *:storage=0:messages=0 - # quota_rule2 = Trash:storage=+100M - #} - -conf.d/90-sieve.conf -^^^^^^^^^^^^^^^^^^^^ -.. code-block:: text - - # uncomment if you want to use sieve (and maybe managesieve) - #plugin { - # recipient_delimiter = + - # sieve = ~/.dovecot.sieve - # sieve_dir = ~/sieve - #} - - -.. _dovecot-sql-conf-ext: - -dovecot-sql.conf.ext -^^^^^^^^^^^^^^^^^^^^ -This file was referenced above in the `passdb` and `userdb` sections of -:ref:`conf-d-10-auth-conf`. - -.. code-block:: text - - driver = pgsql - connect = host=localhost dbname=mailsys user=dovecot password=$Dovecot_PASS - - password_query = \ - SELECT userid AS "user", password FROM dovecotpassword('%Ln', '%Ld') WHERE %Ls - - # uncomment this user_query if you want to use the quota plugin - #user_query = \ - # SELECT home, uid, gid, mail, quota_rule FROM dovecotquotauser('%Ln', '%Ld') - - # otherwise uncomment the following user_query - #user_query = SELECT home, uid, gid, mail FROM dovecotuser('%Ln', '%Ld') - - iterate_query = \ - SELECT local_part AS username, domain_name.domainname AS domain \ - FROM users \ - LEFT JOIN domain_data USING (gid) \ - LEFT JOIN domain_name USING (gid) - - -.. _dovecot-dict-sql-conf-ext: - -dovecot-dict-sql.conf.ext -^^^^^^^^^^^^^^^^^^^^^^^^^ -If you want to use the quota plugin add this lines to your -:file:`dovecot-dict-sql.conf.ext`. -This file was referenced in the `dict` section of :ref:`dovecot2.conf`. - -.. code-block:: text - - connect = host=localhost dbname=mailsys user=dovecot password=$Dovecot_PASS - map { - pattern = priv/quota/storage - table = userquota - username_field = uid - value_field = bytes - } - map { - pattern = priv/quota/messages - table = userquota - username_field = uid - value_field = messages - } - -.. include:: ../ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/installation/install_vmm.rst --- a/doc/web/source/installation/install_vmm.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -============== -Installing vmm -============== -After you've prepared everything, it's time to install vmm. -Change into the :file:`vmm-0.6.2` directory an execute the -:file:`install.sh` script. -You can adjust the installation prefix by modifying line 8 of the script. - -.. code-block:: console - - root@host:~# cd /path/to/vmm-0.6.2 - root@host:/path/to/vmm-0.6.2# ./install.sh - - Don't forget to edit /usr/local/etc/vmm.cfg - or run: vmm cf - and /etc/postfix/pgsql-*.cf files. - - root@host:/path/to/vmm-0.6.2# - -pgsql-\*.cf files ------------------ -After executing the install script you have to edit all :file:`pgsql-{*}.cf` -files in `postconf -h config_directory`. For details see `pgsql_table(5)`_. - -The used parameter values are: - -========= ============= -parameter value -========= ============= -dbname mailsys -hosts localhost -password some_password -user postfix -========= ============= - -So it's easy to use just the :command:`sed` command, in order to edit all -files at once. For example: - -.. code-block:: console - - root@host:~# sed -i "s|\bpostfix\b|_postfix|g" `postconf -h config_directory`/pgsql-*.cf - root@host:~# sed -i "s|some_password|3Q>MO…|g" `postconf -h config_directory`/pgsql-*.cf - root@host:~# - -If your `sed` doesn't like the `-i` option (is unable to edit files in place), -you can do it with :command:`perl`: - -.. code-block:: console - - # perl -pi -e "s|\bpostfix\b|_postfix|g" `postconf -h config_directory`/pgsql-*.cf - -.. note:: Don't forget to start or restart Dovecot and Postfix. - -vmm configure -------------- -Finally you have to edit your :file:`vmm.cfg`. You can edit the configuration -file in your favorite editor or execute :command:`vmm configure`. -vmm's configuration parameters are described in :manpage:`vmm.cfg(5)`. -The initial :doc:`../vmm.cfg` is also well documented. - -Ready, set, go! ---------------- -For a list of available subcommands execute :command:`vmm help`. -For details about the subcommands see :manpage:`vmm(1)` or continue reading -at :doc:`../howto`. - -.. include:: ../ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/installation/postfix_configuration.rst --- a/doc/web/source/installation/postfix_configuration.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -===================== -Postfix configuration -===================== -This page mentions all Postfix configuration parameters, which have to be -modified and/or added in/to the Postfix :file:`main.cf`. - -main.cf -------- -Add or replace the following configuration parameters in the global Postfix -configuration file. -The Postfix PostgreSQL client configuration files (:file:`pgsql-{*}.cf`) -mentioned below will be created when vmm will be installed. - -.. code-block:: text - - sql = pgsql:${config_directory}/ - proxysql = proxy:${sql} - - # relocated users from the database - #relocated_maps = ${proxysql}pgsql-relocated_maps.cf - - # transport settings from our database - transport_maps = ${proxysql}pgsql-transport_maps.cf - - # virtual domains, mailboxes and aliases - virtual_mailbox_domains = ${proxysql}pgsql-virtual_mailbox_domains.cf - virtual_alias_maps = ${proxysql}pgsql-virtual_alias_maps.cf - virtual_minimum_uid = 70000 - virtual_uid_maps = ${sql}pgsql-virtual_uid_maps.cf - virtual_gid_maps = ${sql}pgsql-virtual_gid_maps.cf - virtual_mailbox_base = / - virtual_mailbox_maps = ${proxysql}pgsql-virtual_mailbox_maps.cf - - # dovecot LDA (only recommended with Dovecot v1.x) - #dovecot_destination_recipient_limit = 1 - #virtual_transport = dovecot: - - # dovecot lmtp (requires Dovecot ≧ v2.0.0) - virtual_transport = lmtp:unix:private/dovecot-lmtp - - # dovecot SASL - smtpd_sasl_type = dovecot - smtpd_sasl_path = private/dovecot-auth - smtpd_sasl_auth_enable = yes - # Keep smtpd_sasl_local_domain identical to Dovecot's auth_default_realm: - # empty. Both are empty by default. Let it commented out. - # Read more at: http://wiki2.dovecot.org/Authentication/Mechanisms/DigestMD5 - #smtpd_sasl_local_domain = - smtpd_sasl_security_options = noplaintext, noanonymous - #broken_sasl_auth_clients = yes - - smtpd_recipient_restrictions = - permit_mynetworks - permit_sasl_authenticated - reject_unauth_destination - -master.cf ---------- -.. note:: This step is only necessary if you are still using Dovecot v\ **1**.x - -Add the service `dovecot` to Postfix's master process configuration file. -Append this lines: - -.. code-block:: text - - dovecot unix - n n - - pipe - flags=DORhu user=nobody argv=/usr/local/lib/dovecot/deliver -f ${sender} - -d ${user}@${nexthop} -n -m ${extension} - -The command of the `argv` attribute points to the -:ref:`root SETUID copy of deliver <root-setuid-copy-of-deliver>`. -For more details about the `flags` used above see: `pipe(8)`_. -All other arguments are explained in the Dovecot LDA_ documentation. - -Using Dovecot's LMTP --------------------- -In order to use Dovecot's LMTP_ as `virtual_transport` with Postfix make sure -you have have: - - ‣ `lmtp` in your `protocols` setting (:ref:`dovecot2.conf`) - ‣ configured a `lmtp` listener: `service lmtp {}` - (:ref:`conf-d-10-master.conf`) - ‣ set `lmtp:unix:private/dovecot-lmtp` as the `domain.transport` in your - :file:`vmm.cfg`. - -If you want to switch the transport of existing domains and/or accounts, you -can use the subcommands :ref:`domaintransport` and :ref:`usertransport`. - -.. include:: ../ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/installation/postgresql_configuration.rst --- a/doc/web/source/installation/postgresql_configuration.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -======================== -PostgreSQL configuration -======================== -Adjust pg_hba.conf ------------------- -The connection to a PostgreSQL server can be established either through a -local Unix-domain socket or a TCP/IP socket. The :file:`pg_hba.conf` file -defines which users/groups are allowed to connect from which clients and -how they have to authenticate. -The :file:`pg_hba.conf` file is mostly stored in the database cluster's data -directory. The data directory is often :file:`/usr/local/pgsql/data` or -:file:`/var/lib/pgsql/data.` On Debian GNU/Linux systems the -:file:`pg_hba.conf` is located in :file:`/etc/postgresql/{VERSION}/{CLUSTER}` -(for example: :file:`/etc/postgresql/9.1/main`). - -Some information about the :file:`pg_hba.conf` is available in the PostgreSQL -Wiki/`Client Authentication`_, even more detailed in the pg_hba.conf_ -documentation. - -For TCP/IP connections -^^^^^^^^^^^^^^^^^^^^^^ -Add a line like the following to your :file:`pg_hba.conf` if you want to -connect via a TCP/IP connection to the PostgreSQL server. -Make sure to adjust the CIDR address if PostgreSQL is running on a -different system: - -.. code-block:: text - :emphasize-lines: 2 - - # IPv4 local connections: - host mailsys +mailsys 127.0.0.1/32 md5 - -For Unix-domain socket connections -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you want to use PostgreSQL's local Unix domain socket for database -connections add a line like the second one to your :file:`pg_hba.conf`: - -.. code-block:: text - :emphasize-lines: 2 - - # "local" is for Unix domain socket connections only - local mailsys +mailsys md5 - local all all ident sameuser - -.. note:: `ident sameuser` will not work, because `dovecot-auth` will be - executed by the unprivileged user `doveauth` - (see :ref:`System Preparation <doveauth>`), not by the `dovecot` user. - -Create database users and the database --------------------------------------- -You should create some database users for vmm, Dovecot and Postfix as well -as their group. -Each of them will get different privileges granted. -Finally create a new database. - -Create a database superuser, which will be able to create users and databases, -if necessary. If you have sudo privileges run: - -.. code-block:: console - - user@host:~$ sudo su - postgres - [sudo] password for user: - postgres@host:~$ createuser -s -d -r -E -e -P $USERNAME - -If you are root, omit the :command:`sudo` command. Just execute -:command:`su - postgres` and create the database superuser. - -Start :command:`psql` as superuser and connect to the database `template1`: - -.. code-block:: console - - user@host:~$ psql template1 - -Then create users, their group and the empty database: - -.. code-block:: postgresql-console - - template1=# CREATE ROLE vmm LOGIN ENCRYPTED PASSWORD 'DB PASSWORD for vmm'; - template1=# CREATE ROLE dovecot LOGIN ENCRYPTED password 'DB PASSWORD for Dovecot'; - template1=# CREATE ROLE postfix LOGIN ENCRYPTED password 'DB PASSWORD for Postfix'; - template1=# CREATE ROLE mailsys WITH USER postfix, dovecot, vmm; - template1=# CREATE DATABASE mailsys WITH OWNER vmm ENCODING 'UTF8'; - template1=# \q - -Import tables and functions ---------------------------- -Now start :command:`psql` and connect as your `vmm` user to the database -`mailsys`: - -.. code-block:: console - - user@host:~$ psql mailsys vmm -W -h localhost - -In PostgreSQL's terminal-based front-end import the database layout/tables -and functions into your database. - -Dovecot v1.2.x/v2.0.x/v2.1.x -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. code-block:: postgresql-console - - mailsys=> \i /path/to/vmm-0.6.2/pgsql/create_tables-dovecot-1.2.x.pgsql - mailsys=> \q - -Dovecot v1.0.x/v1.1.x -^^^^^^^^^^^^^^^^^^^^^ -.. code-block:: postgresql-console - - mailsys=> \i /path/to/vmm-0.6.2/pgsql/create_tables.pgsql - mailsys=> \q - -Set database permissions ------------------------- -.. include:: ../pgsql_set_permissionspermissions.rst - -.. include:: ../ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/installation/prerequisites.rst --- a/doc/web/source/installation/prerequisites.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -========================== -Installation Prerequisites -========================== -You already should have installed and configured Postfix and Dovecot with -PostgreSQL support. You also need access to a local or remote PostgreSQL -server. - -Check for pgsql support in Dovecot and Postfix ----------------------------------------------- -To verify that your Dovecot and Postfix installation has support for -PostgreSQL use the :command:`postconf` and :command:`dovecot` commands as -shown below: - -.. code-block:: console - - root@host:~# postconf -m | grep pgsql - pgsql - root@host:~# postconf -a | grep dovecot - dovecot - root@host:~# dovecot --build-options | grep postgresql - SQL drivers: mysql postgresql sqlite - -vmm depends on Python (≥ 2.4.0) and Psycopg_ (≥ 2.0) or pyPgSQL_ (≥ 2.5.1) -[#]_. Psycopg and pyPgSQL are depending on parts of the *eGenix.com mx Base -Distribution* (mxDateTime_ and mxTools_). - -If you are using Python ≤ 2.5.0: - - ‣ if you want to store your users' passwords as ``PLAIN-MD4`` digest in - the database, vmm will try to use ``Crypto.Hash.MD4`` from PyCrypto_ - ‣ if you are using Dovecot ≥ v1.1.0 and you want to store your users' - passwords as ``SHA256`` or ``SSHA256`` hashes, vmm will try to use - ``Crypto.Hash.SHA256`` from PyCrypto. For ``SHA256``/``SSHA256`` you - should have installed PyCrypto, at least in version 2.1.0alpha1. - - When the Crypto.Hash module couldn't be imported, vmm will use - dovecotpw/doveadm, if the *misc.password_scheme* setting in your - :file:`vmm.cfg` is set to ``PLAIN-MD4``, ``SHA256`` or ``SSHA256``. - -If your Dovecot and/or Postfix installation shouldn't support PostgreSQL you -could possibly fix this by installing the missing package (see below) or by -recompiling the corresponding part. - -Package names by OS/Distribution --------------------------------- -Debian GNU/Linux (Squeeze/Wheezy) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ‣ `postfix <http://packages.debian.org/postfix>`_ and - `postfix-pgsql <http://packages.debian.org/postfix-pgsql>`_ - ‣ Squeeze: - - * `dovecot-common <http://packages.debian.org/dovecot-common>`_ - - ‣ Wheezy (and Squeeze backports): - - * `dovecot-core <http://packages.debian.org/dovecot-core>`_ and - `dovecot-lmtpd <http://packages.debian.org/dovecot-lmtpd>`_ - - ‣ `dovecot-imapd <http://packages.debian.org/dovecot-imapd>`_ and/or - `dovecot-pop3d <http://packages.debian.org/dovecot-pop3d>`_ - ‣ `postgresql-client <http://packages.debian.org/postgresql-client>`_ - (or `postgresql <http://packages.debian.org/postgresql>`_ , if you do not - have a dedicated PostgreSQL server.) - ‣ `python <http://packages.debian.org/python>`_, - `python-egenix-mxdatetime \ - <http://packages.debian.org/python-egenix-mxdatetime>`_ - and `python-psycopg2 <http://packages.debian.org/python-psycopg2>`_ - optionally `python-crypto <http://packages.debian.org/python-crypto>`_ - ‣ `gettext <http://packages.debian.org/gettext>`_ - -FreeBSD -^^^^^^^ -Packages or build from ports: - ‣ dovecot - ‣ postfix - ‣ postgresql-client (and postgresql-server, if you do not have a dedicated - PostgreSQL server.) - ‣ python25, py25-mx-base and py25-pyPgSQL optionally py25-pycrypto - -Gentoo Linux -^^^^^^^^^^^^ - ‣ `dev-python/pypgsql <http://gentoo-portage.com/dev-python/pypgsql>`_ - ‣ `mail-mta/postfix <http://gentoo-portage.com/mail-mta/postfix>`_ - ‣ `net-mail/dovecot <http://gentoo-portage.com/net-mail/dovecot>`_ - ‣ `dev-db/postgresql-base <http://gentoo-portage.com/dev-db/postgresql-base>`_ - ‣ `dev-db/postgresql-server \ - <http://gentoo-portage.com/dev-db/postgresql-server>`_ - -Applied use-Flags (/etc/portage/package.use):: - - mail-mta/postfix dovecot-sasl postgres -pam sasl - net-mail/dovecot postgres -pam pop3d sieve - dev-db/postgresql-server -perl - -OpenBSD (5.x) -^^^^^^^^^^^^^ -Packages - ‣ postfix-2.x.y-pgsql - ‣ dovecot-2.x.y and dovecot-postgresql-2.x.y - ‣ postgresql-client - ‣ python-2.7.x, py-psycopg2 and optionally py-crypto - -Or build the above mentioned software from ports. - -openSUSE Linux -^^^^^^^^^^^^^^ - ‣ postfix and postfix-postgresql - ‣ postgresql-server and postgresql - ‣ dovecot - ‣ python and pyPgSQL optionally python-crypto - - -.. rubric:: Footnotes -.. [#] Beginning with version 0.7.0 of vmm support for pyPgSQL will be dropped. - -.. include:: ../ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/installation/system_preparation.rst --- a/doc/web/source/installation/system_preparation.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -================== -System Preparation -================== -.. _doveauth: - -We have to create a system user, named `doveauth`. -The `doveauth` user will execute Dovecot's authentication processes. - -We will also create an additional system group, named `dovemail`. -The GID of the group `dovemail` will be the supplementary GID for all -mail related Dovecot processes, e.g. the `dict` service for quota limits. - -And finally we will create the ``base_directory``, with it's subdirectories. -It is the location for all domain directories and the virtual user's home -directories. - -The example below shows the steps executed on a Debian GNU/Linux system. - -.. code-block:: console - - root@host:~# adduser --system --home /nonexistent --no-create-home --group \ - > --disabled-login --gecos "Dovecot IMAP/POP3 authentication user" doveauth - root@host:~# addgroup --system dovemail - root@host:~# mkdir /srv/mail - root@host:~# cd /srv/mail - root@host:/srv/mail# mkdir 0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z - root@host:/srv/mail# chmod 771 /srv/mail - root@host:/srv/mail# chmod 751 /srv/mail/* - -.. _root-setuid-copy-of-deliver: - -root SETUID copy of deliver ---------------------------- -.. note:: This step is only necessary if you are still using Dovecot v\ **1**.x - -For security reasons the permissions in the domain/user directories will -be very restricted. -Each user will get its own unique UID_ and the GID_ from the domain. -So it will be only possible for a user of the domain to access the domain -directory (read only) and the user will get granted read write access only -for its home directory. - -For this reason it is necessary to provide a setuid_-root copy of Dovecot's -LDA_ (:command:`deliver`) for Postfix. -Because Postfix will refuse to execute commands with root privileges, or -with the privileges of the mail system owner (normally `postfix`) you should -`nobody` let do the job. -Therefore the permissions will be set very restrictive again. -Only `nobody` will be able to execute the setuid-root copy of -:command:`deliver`. - -.. code-block:: console - - root@host:~# mkdir -p /usr/local/lib/dovecot - root@host:~# chmod 700 /usr/local/lib/dovecot - root@host:~# chown nobody /usr/local/lib/dovecot - root@host:~# cp /usr/lib/dovecot/deliver /usr/local/lib/dovecot/ - root@host:~# chown root:`id -g nobody` /usr/local/lib/dovecot/deliver - root@host:~# chmod u+s,o-rwx /usr/local/lib/dovecot/deliver - -.. include:: ../ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/pgsql_set_permissionspermissions.rst --- a/doc/web/source/pgsql_set_permissionspermissions.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -There's a python script which grants permissions to your Dovecot and Postfix -database users. - -.. code-block:: console - - user@host:~$ python /path/to/vmm-0.6.2/pgsql/set-permissions.py -h - Usage: set-permissions.py OPTIONS - - Set permissions for Dovecot and Postfix in the vmm database. - - Options: - -h, --help show this help message and exit - -a, --askpass Prompt for the database password. - -H HOST, --host=HOST Hostname or IP address of the database server. Leave - blank in order to use the default Unix-domain socket. - -n NAME, --name=NAME Specifies the name of the database to connect to. - Default: mailsys - -p PASS, --pass=PASS Password for the database connection. - -P PORT, --port=PORT Specifies the TCP port or the local Unix-domain socket - file extension on which the server is listening for - connections. Default: 5432 - -U USER, --user=USER Connect to the database as the user USER instead of - the default: root - -D USER, --dovecot=USER - Database user name of the Dovecot database user. - Default: dovecot - -M USER, --postfix=USER - Database user name of the Postfix (MTA) database - user. Default: postfix - user@host:~$ python /path/to/vmm-0.6.2/pgsql/set-permissions.py -a -H 127.0.0.1 -U vmm - Password: - user@host:~$ - diff -r 659c4476c57c -r b678a1c43027 doc/web/source/release_history.rst --- a/doc/web/source/release_history.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -====================== -Release history of vmm -====================== - -=========== ============ ====================================================== -Version Release Date Download URL -=========== ============ ====================================================== -vmm-0.6.2 Feb 01 2014 https://sourceforge.net/projects/vmm/files/vmm/0.6.2 -vmm-0.6.1 Oct 03 2012 https://sourceforge.net/projects/vmm/files/vmm/0.6.1 -vmm-0.6.0 Jun 28 2012 https://sourceforge.net/projects/vmm/files/vmm/0.6.0 -vmm-0.5.2 Sep 09 2009 https://sourceforge.net/projects/vmm/files/vmm/0.5.2 -vmm-0.5.1 Aug 12 2009 https://sourceforge.net/projects/vmm/files/vmm/0.5.1 -vmm-0.5 Nov 27 2008 https://sourceforge.net/projects/vmm/files/vmm/0.5 -vmm-0.4-r41 May 02 2008 https://sourceforge.net/projects/vmm/files/vmm/0.4-r41 -vmm-0.4 May 01 2008 https://sourceforge.net/projects/vmm/files/vmm/0.4 -vmm-0.3.1 Jan 08 2008 https://sourceforge.net/projects/vmm/files/vmm/0.3.1 -vmm-0.3 Jan 06 2008 https://sourceforge.net/projects/vmm/files/vmm/0.3 -=========== ============ ====================================================== diff -r 659c4476c57c -r b678a1c43027 doc/web/source/substitutions.rst --- a/doc/web/source/substitutions.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -.. |curr_vers_rel_date| replace:: The most current version of vmm is 0.6.2, - released on 01 February 2014. -.. |rel_hist| replace:: Older releases are listed in the :doc:`release_history`. - diff -r 659c4476c57c -r b678a1c43027 doc/web/source/upgrade.rst --- a/doc/web/source/upgrade.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -============= -Upgrading vmm -============= -Upgrade instructions for different versions of vmm. - -.. toctree:: - :maxdepth: 1 - - upgrade/0.5-0.6 - upgrade/0.4.x-0.5 diff -r 659c4476c57c -r b678a1c43027 doc/web/source/upgrade/0.4.x-0.5.rst --- a/doc/web/source/upgrade/0.4.x-0.5.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -====================== -Upgrading to vmm 0.5.x -====================== -This page is valid only for vmm-0.4/vmm-0.4-r41 and vmm-0.5/vmm-0.5.1. -If you are using vmm-0.3.x please upgrade first to -`vmm-0.4-r41 <https://sourceforge.net/projects/vmm/files/vmm/0.4-r41>`_. - -Upgrading from vmm-0.4.x ------------------------- -Database backup -^^^^^^^^^^^^^^^ -It is always wise to back up your database from time to time. -Particularly with regard to an impending structure modification. - -Example: Backing up the `mailsys` database with pg_dump_. - -.. code-block:: console - - root@host:~# pg_dump -h localhost -U vmm -W mailsys > mailsys-0.4.sql - -Stopping Postfix and Dovecot -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Before updating the database you have to stop Postfix and Dovecot. - -.. code-block:: console - - root@host:~# /etc/init.d/postfix stop - Stopping Postfix Mail Transport Agent: postfix. - root@host:~# /etc/init.d/dovecot stop - Stopping IMAP/POP3 mail server: dovecot. - -Database update -^^^^^^^^^^^^^^^ -Connect as your `vmm` database user to your database. - -.. code-block:: console - - root@host:~# psql mailsys vmm -W -h localhost - -In the PostgreSQL interactive terminal you have to run the following -commands to perform the update. - -.. code-block:: postgresql-console - - mailsys=> \i /path/to/vmm-0.5.2/update_tables_0.4.x-0.5.pgsql - mailsys=> GRANT SELECT ON postfix_alias TO postfix; - mailsys=> \q - -.. _database-update-for-dovecot-v1-2-x: - -Database update for Dovecot v1.2.x -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -When you are already using Dovecot v1.2.x, you have to perform one or two -**additional** database updates. - -.. code-block:: postgresql-console - - mailsys=> \i /path/to/vmm-0.5.2/update_tables_0.5.x_for_dovecot-1.2.x.pgsql - mailsys=> GRANT SELECT ON dovecot_password TO dovecot; - mailsys=> -- If you are using the function dovecotpassword() in the - mailsys=> -- password_query setting of your dovecot-sql.conf update it also: - mailsys=> \i /path/to/vmm-0.5.2/update_types_and_functions_0.5.x_for_dovecot-1.2.x.pgsql - mailsys=> \q - -.. _adjusting-permissions-of-the-setuid-root-deliver-copy: - -Adjusting permissions of the setuid root deliver copy -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Starting with Dovecot version 1.2.0 the LDA ``deliver`` will no longer -work, if the binary has the setuid-root bit set **and** it's executable -for everyone. -Independent of the directory permissions, where the ``deliver`` binary -is located. -For this reason you have to adjust the permission of the ``deliver`` binary. - -.. code-block:: console - - root@host:~# chown root:`id -g nobody` /usr/local/lib/dovecot/deliver - root@host:~# chmod u+s,o-rwx /usr/local/lib/dovecot/deliver - -.. _check-update-postfix-master-cf: - -Check/update Postfix' master.cf -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -In prior setups the service *dovecot* was configured slightly different. -If you have set the command attribute user to ``nobody:mail``, either -remove the group *mail* or replace it with the group *nobody* or *nogroup*. -The second line of the service *dovecot* entry should look similar to this:: - - flags=DORhu user=nobody argv=/usr/local/lib/dovecot/deliver … - -Start Dovecot and Postfix again -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -After a successfully update start Dovecot and Postfix again. - -.. code-block:: console - - root@host:~# /etc/init.d/dovecot start - Starting IMAP/POP3 mail server: dovecot. - root@host:~# /etc/init.d/postfix start - Starting Postfix Mail Transport Agent: postfix. - -Upgrade vmm -^^^^^^^^^^^ -Finally execute the ``upgrade.sh`` script to install the new code and -update your ``/usr/local/etc/vmm.cfg``. - -.. code-block:: console - - root@host:~# cd /path/to/vmm-0.5.2 - root@host:/path/to/vmm-0.5.2# ./upgrade.sh - - Please have a look at your /usr/local/etc/vmm.cfg - and verify the value from option 'postconf' in section 'bin'. - - root@host:/path/to/vmm-0.5.2# - -Upgrading from vmm-0.5.x ------------------------- -Upgrade vmm -^^^^^^^^^^^ -When you have already installed vmm-0.5 or vmm-0.5.1 only a single step is -necessary to update your vmm installation. -cd in the source directory and execute the ``upgrade.sh`` script. -That's it. - -.. code-block:: console - - root@host:~# cd /path/to/vmm-0.5.2 - root@host:/path/to/vmm-0.5.2# ./upgrade.sh - root@host:/path/to/vmm-0.5.2# - -When you are already using Dovecot ≧ v1.2.0, you should also respect -following points: - - ‣ :ref:`database-update-for-dovecot-v1-2-x` - ‣ :ref:`adjusting-permissions-of-the-setuid-root-deliver-copy` - ‣ :ref:`check-update-postfix-master-cf` - -.. include:: ../ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/upgrade/0.5-0.6.rst --- a/doc/web/source/upgrade/0.5-0.6.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ -====================== -Upgrading to vmm 0.6.x -====================== -This document describes the procedure to upgrade a vmm-0.5.2 installation -to version 0.6.x - -If you still have installed vmm-0.4/vmm-0.4-r41 you have to proceed this -step first: - - ‣ :doc:`0.4.x-0.5` - -Upgrading from vmm-0.5.2 ------------------------- - -Stop Postfix and Dovecot -^^^^^^^^^^^^^^^^^^^^^^^^ -Before updating your database layout you have to stop Postfix and Dovecot. - -.. code-block:: console - - root@host:~# /etc/init.d/postfix stop - Stopping Postfix Mail Transport Agent: postfix. - root@host:~# /etc/init.d/dovecot stop - Stopping IMAP/POP3 mail server: dovecot. - -Create a database backup -^^^^^^^^^^^^^^^^^^^^^^^^ -It is always wise to back up your database from time to time. -Particularly with regard to an impending structure modification. - - -Example: Backing up the `mailsys` database with pg_dump_. - -.. code-block:: console - - user@host:~$ pg_dump -h localhost -U vmm -W mailsys > mailsys-0.5.2.sql - -Database update -^^^^^^^^^^^^^^^ -Connect as your `vmm` database user to your database. - -.. code-block:: console - - user@host:~$ psql mailsys vmm -W -h localhost - -In the PostgreSQL interactive terminal you have to run one of the following -commands to perform the update. - -Dovecot v1.2.x/v2.0.x/v2.1.x -"""""""""""""""""""""""""""" -.. code-block:: postgresql-console - - mailsys=> \i /path/to/vmm-0.6.2/pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql - mailsys=> \q - -Dovecot v1.0.x/v1.1.x -""""""""""""""""""""" -.. code-block:: postgresql-console - - mailsys=> \i /path/to/vmm-0.6.2/pgsql/update_tables_0.5.x-0.6.pgsql - mailsys=> \q - -.. _set-database-permissions: - -Set database permissions -^^^^^^^^^^^^^^^^^^^^^^^^ -.. include:: ../pgsql_set_permissionspermissions.rst - -Start Dovecot and Postfix again -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. warning:: All the views (*dovecot_…* and *postfix_…*) have been - replaced by database functions. - So you have to adjust all your ``postfix/pgsql-*.cf`` files and also your - ``/etc/dovecot/dovecot-sql.conf`` or ``/etc/dovecot/dovecot-sql.conf.ext``. - - See the `vmm-0.6.2/postfix/pgsql-*.cf` files and - :ref:`Dovecot configuration <dovecot-sql-conf-ext>`/`dovecot-sql.conf.ext` - or :ref:`Dovecot configuration <dovecot-sql-conf>`/`dovecot-sql-conf`. - -After a successfully update start Dovecot and Postfix again. - -.. code-block:: console - - root@host:~# /etc/init.d/dovecot start - Starting IMAP/POP3 mail server: dovecot. - root@host:~# /etc/init.d/postfix start - Starting Postfix Mail Transport Agent: postfix. - -Upgrade vmm -^^^^^^^^^^^ -Finally execute the :file:`upgrade.sh` script. -This will install the new code and also update your :file:`vmm.cfg`. - -.. code-block:: console - - root@host:~# cd /path/to/vmm-0.6.2 - root@host:/path/to/vmm-0.6.2# ./upgrade.sh - Please have a look at your configuration: /usr/local/etc/vmm.cfg - This are your Modified/Renamed/New settings: - R account.delete_directory = false - R account.directory_mode = 448 - R account.disk_usage = false - R domain.delete_directory = false - R domain.directory_mode = 504 - R domain.force_deletion = false - R domain.imap = true - R domain.pop3 = true - R domain.sieve = true - R domain.smtp = true - R domain.transport = dovecot: - R mailbox.folders = Drafts:Sent:Templates:Trash - R mailbox.root = Maildir - R misc.base_directory = /srv/mail - M misc.dovecot_version = 2.1.7 - R misc.dovecot_version = 2.1.7 - R misc.password_scheme = PLAIN - - Removed section "config" with option "done" (obsolte) - - Removed option "gid_mail" from section "misc" (obsolte) - - -Upgrading from vmm-0.6.0 ------------------------- - -Database fixes -^^^^^^^^^^^^^^ -Due to an error in :ref:`usertransport`'s argument parsing, it is possible -that some users' transport-ID points to the erroneous transport *domain*. -To fix that error in your database, execute the following SQL statement: - -.. code-block:: psql - - UPDATE users SET tid = NULL - WHERE tid = (SELECT tid FROM transport WHERE transport = 'domain'); - -If you are using Dovecot < v.1.2.0, you have to replace the database -function *dovecotpassword()*. -The *service_set.ssid* was selected unconditionally. -This may cause an empty result, which will make logins impossible. -To replace the function execute the following SQL statement: - -.. code-block:: psql - - CREATE OR REPLACE FUNCTION dovecotpassword( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotpassword - AS $$ - DECLARE - record dovecotpassword; - userid varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT userid, passwd, smtp, pop3, imap, managesieve - FROM users, service_set, domain_data - WHERE users.gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - AND users.gid = domain_data.gid - AND CASE WHEN - users.ssid IS NOT NULL - THEN - service_set.ssid = users.ssid - ELSE - service_set.ssid = domain_data.ssid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; - $$ LANGUAGE plpgsql STABLE - RETURNS NULL ON NULL INPUT - EXTERNAL SECURITY INVOKER; - -Upgrade vmm -^^^^^^^^^^^ -Execute the :file:`upgrade.sh`, in order to install the updated code. - -Upgrading from vmm-0.6.1 ------------------------- -If you have already installed vmm-6.0.1, simply execute the -:file:`upgrade.sh` script. - -Upgrade to Dovecot ≧ v1.2.beta2 -------------------------------- -When you are upgrading your old Dovecot (< v.1.2.beta2) to a newer version, -≧ v1.2.beta2, you also have to update the database layout. -After you have backed up your database, you have to apply the changes from -the file :file:`dovecot_update_v1.2+.pgsql` to your database. -(The file is currently only available from hg: -`dovecot_update_v1.2+.pgsql <http://hg.localdomain.org/vmm/raw-file/bb23693e5fc9/pgsql/dovecot_update_v1.2%2B.pgsql>`_) - -Connect as your `vmm` database user to your database. - -.. code-block:: console - - user@host:~$ psql mailsys vmm -W -h localhost - -Then do the database update: - -.. code-block:: postgresql-console - - mailsys=> \i /path/to/dovecot_update_v1.2+.pgsql - mailsys=> \q - -Finally :ref:`set-database-permissions`. - -.. include:: ../ext_references.rst diff -r 659c4476c57c -r b678a1c43027 doc/web/source/vmm.cfg.rst --- a/doc/web/source/vmm.cfg.rst Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -========================== -Configuration file for vmm -========================== -When you have installed vmm as described in :doc:`installation/install_vmm` -a copy of :download:`vmm.cfg <_static/vmm.cfg>` will be stored in -:file:`{$PREFIX}/share/doc/vmm`. - -.. literalinclude:: _static/vmm.cfg - :language: cfg - diff -r 659c4476c57c -r b678a1c43027 install.sh --- a/install.sh Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -#!/bin/sh -# -# Installation script for the Virtual Mail Manager -# run: ./install.sh - -LANG=C -PATH=/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin -PREFIX=/usr/local - -PF_CONFDIR=$(postconf -h config_directory) -PF_GID=$(id -g $(postconf -h mail_owner)) -LOCALE_DIR=${PREFIX}/share/locale -DOC_DIR=${PREFIX}/share/doc/vmm -if [ ${PREFIX} = "/usr" ]; then - MANDIR=${PREFIX}/share/man - SYSCONFDIR=/etc -else - MANDIR=${PREFIX}/man - SYSCONFDIR=${PREFIX}/etc -fi -DOCS="ChangeLog Configure.Dovecot_2 COPYING INSTALL NEWS README" - -INSTALL_OPTS="-g 0 -o 0 -p" -INSTALL_OPTS_CF="-b -m 0640 -g ${PF_GID} -o 0 -p" - -if [ $(id -u) -ne 0 ]; then - echo "Run this script as root." - exit 1 -fi - -python setup.py -q install --force --prefix ${PREFIX} -python setup.py clean --all >/dev/null - -[ -d ${SYSCONFDIR} ] || mkdir -m 0755 -p ${SYSCONFDIR} -install -b -m 0600 ${INSTALL_OPTS} vmm.cfg ${SYSCONFDIR}/ -install ${INSTALL_OPTS_CF} postfix/pgsql-*.cf ${PF_CONFDIR}/ -install -m 0700 ${INSTALL_OPTS} vmm ${PREFIX}/sbin - -[ -d ${LOCALE_DIR} ] || mkdir -m 0755 -p ${LOCALE_DIR} -cd po -for po in $(ls -1 *.po); do - lang=$(basename ${po} .po) - ddir=${LOCALE_DIR}/${lang}/LC_MESSAGES - [ -d ${ddir} ] || mkdir -m 0755 -p ${ddir} - msgfmt -o ${LOCALE_DIR}/${lang}/LC_MESSAGES/vmm.mo ${po} -done -cd - >/dev/null - -cd man -[ -d ${MANDIR}/man1 ] || mkdir -m 0755 -p ${MANDIR}/man1 -install -m 0644 ${INSTALL_OPTS} man1/vmm.1 ${MANDIR}/man1 - -[ -d ${MANDIR}/man5 ] || mkdir -m 0755 -p ${MANDIR}/man5 -install -m 0644 ${INSTALL_OPTS} man5/vmm.cfg.5 ${MANDIR}/man5 - -for l in $(find . -maxdepth 1 -mindepth 1 -type d \! -name man\?) -do - for s in man1 man5; do - [ -d ${MANDIR}/${l}/${s} ] || mkdir -m 0755 -p ${MANDIR}/${l}/${s} - done - if [ -f ${l}/man1/vmm.1 ]; then - install -m 0644 ${INSTALL_OPTS} ${l}/man1/vmm.1 ${MANDIR}/${l}/man1 - fi - if [ -f ${l}/man5/vmm.cfg.5 ]; then - install -m 0644 ${INSTALL_OPTS} ${l}/man5/vmm.cfg.5 ${MANDIR}/${l}/man5 - fi -done -cd - >/dev/null - -[ -d ${DOC_DIR} ] || mkdir -m 0755 -p ${DOC_DIR} -for DOC in ${DOCS}; do - install -m 0644 ${INSTALL_OPTS} ${DOC} ${DOC_DIR} -done - -[ -d ${DOC_DIR}/examples ] || mkdir -m 0755 -p ${DOC_DIR}/examples -install -m 0644 ${INSTALL_OPTS} postfix/pgsql-*.cf ${DOC_DIR}/examples -install -m 0644 ${INSTALL_OPTS} vmm.cfg ${DOC_DIR}/examples - -echo -echo "Don't forget to edit ${PREFIX}/etc/vmm.cfg - or run: vmm cf" -echo "and ${PF_CONFDIR}/pgsql-*.cf files." -echo diff -r 659c4476c57c -r b678a1c43027 man/de/man1/vmm.1 --- a/man/de/man1/vmm.1 Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1089 +0,0 @@ -.TH "VMM" "1" "2012-09-27" "vmm 0.6" "vmm" -.SH NAME -vmm \- Kommandozeilenprogramm zur Verwaltung von E\-Mail\-Domains/\-Konten -und \-Aliase. -.\" ----------------------------------------------------------------------- -.SH ÜBERSICHT -.B vmm -.IR Unterbefehl " [" "Argument ..." ] -.\" ----------------------------------------------------------------------- -.SH BESCHREIBUNG -.B vmm -(a virtual mail manager) ist das einfach zu bedienende -Kommandozeilenprogramm für Administratoren und Postmaster, zur Verwaltung -von (Alias\-) Domains, Konten, Alias\-Adressen und sogenannten Relocated -Users. -Es ermöglicht die schnelle und einfache Verwaltung des Mailservers. -.br -Es wurde für Dovecot und Postfix mit einem PostgreSQL\-Backend entwickelt. -.PP -Von jedem -.I Unterbefehl -gibt es jeweils eine lange und kurze Variante. -Die Kurzform ist in Klammern geschrieben. -Bei beiden Formen ist die Groß\-/Kleinschreibung zu berücksichtigen. -.PP -Die meisten -.IR Unterbefehl e -erwarten ein oder mehrere -.IR Argument e. -.\" ----------------------------------------------------------------------- -.SH ARGUMENTE -.TP 12 -.I address -Die komplette E\-Mail\-Adresse -.RI ( local\-part @ fqdn ) -eines Kontos, Aliases oder Relocated Users. -.\" -------------------------- -.TP -.I destination -Ist entweder eine E\-Mail\-Adresse, wenn sie in Verbindung mit -.I "ALIAS UNTERBEFEHLEN" -verwendet wird, oder ein -.I fqdn -in Verbindung mit -.IR "ALIASDOMAIN UNTERBEFEHLEN" . -.\" -------------------------- -.TP -.I fqdn -Der voll qualifizierten Domain\-Namen \(em ohne den abschließenden Punkt -\(em einer Domain oder Alias\-Domain. -.\" -------------------------- -.TP -.I messages -Ein Integer\-Wert, der das maximal nutzbare Kontingent als Anzahl von -Nachrichten festlegt. -.br -Der Wert -.B 0 -(null) bedeutet unbegrenzt \(em kein Quota\-Limit als Anzahl von -Nachrichten. -.\" -------------------------- -.TP -.I option -ist der Name einer Konfigurationsoption mit vorangestellter -Konfigurations\-Sektion, getrennt durch einen Punkt. -Zum Beispiel: -.IB misc . transport -.br -Alle Konfigurationsoptionen werden in -.BR vmm.cfg (5) -beschrieben. -.\" -------------------------- -.TP -.I service -Der Name eines Services, der gewöhnlicherweise in Verbindung mit Dovecot -genutzt wird. -Folgende Services werden unterstützt: -.BR imap ", " pop3 ", " sieve " und " smtp . -.\" -------------------------- -.TP -.I storage -Bestimmt das maximal nutzbare Kontingent in Bytes. -Eines der folgenden Präfixe kann dem dem ganzzahligen Wert angehängt -werden: -.BR b " (Bytes), " k " (Kilobytes), " M " (Megabytes) oder " G -(Gigabytes). -.br -Der Wert -.B 0 -(null) bedeutet unbegrenzt \(em kein Quota\-Limit in Bytes. -.\" -------------------------- -.TP -.I transport -ein Transport für Postfix, angegeben in der Form: -.IB transport : -oder -.IB transport :\c -.IR nexthop . -Siehe -.BR transport (5) -für weitere Details. -.\" ----------------------------------------------------------------------- -.SH ALLGEMEINE UNTERBEFEHLE -.SS configget (cg) -.BI "vmm configget" " option" -.PP -Dieser Unterbefehl wird verwendet, um den aktuellen Wert der übergebenen -.I option -anzuzeigen. -.PP -Beispiel: -.PP -.nf -.B vmm configget misc.crypt_sha512_rounds -misc.crypt_sha512_rounds = 5000 -.fi -.\" -------------------------- -.SS configset (cs) -.B vmm configset -.I option value -.PP -Verwenden Sie diesen Unterbefehl, um einer einzelnen Konfigurationsoption -einen neuen Wert zuzuweisen. -.I option -ist der Name der Konfigurationsoption, -.I value -ist der Wert, der der Konfigurationsoption zugewiesen wird. -.IP Hinweis: -Diese Unterbefehl erstellt eine neue -.IR vmm.cfg , -ohne Kommentare. -Die aktuelle Konfigurationsdatei wird als -.IR vmm.cfg.bak -gesichert. -.PP -Beispiel: -.PP -.nf -.B vmm configget domain.transport -domain.transport = dovecot: -.B vmm configset domain.transport lmtp:unix:private/dovecot\-lmtp -.B vmm cg domain.transport -domain.transport = lmtp:unix:private/dovecot\-lmtp -.fi -.\" ------------------------------------ -.SS configure (cf) -.B vmm configure -.RI [ section ] -.PP -Startet die interaktiven Konfiguration für alle Konfigurationssektionen. -.PP -Dabei wird der aktuell konfigurierte Wert einer jeden Option in eckigen -Klammern ausgegeben. -Sollte kein Wert konfiguriert sein, wird der Vorgabewert der jeweiligen -Option in in eckigen Klammern angezeigt. -Um den angezeigten Wert unverändert zu übernehmen, ist dieser mit der -Eingabe\-Taste zu bestätigen. -.PP -Wurde das optionale Argument -.I section -angegeben, werden nur die Optionen der angegebenen Sektion angezeigt und -können geändert werden. -Folgende Sektionen sind vorhanden: -.RS -.TP 10 -.B account -Konto Einstellungen -.TP -.B bin -Pfade zu externen Binär\-Dateien -.TP -.B database -Datenbank Einstellungen -.TP -.B domain -Domain Einstellungen -.TP -.B mailbox -Mailbox Einstellungen -.TP -.B misc -Verschiedene Einstellungen -.RE -.PP -Die Konfigurationsoptionen werden in -.BR vmm.cfg (5) -beschrieben. -.IP Hinweis: -Diese Unterbefehl erstellt eine neue -.IR vmm.cfg , -ohne Kommentare. -Die aktuelle Konfigurationsdatei wird als -.IR vmm.cfg.bak -gesichert. -.PP -Beispiel: -.PP -.nf -.B vmm configure mailbox -Konfigurationsdatei wird verwendet: /root/vmm.cfg - -* Konfigurationsabschnitt: »mailbox« -Neuer Wert für Option folders [Drafts:Sent:Templates:Trash]: -Neuer Wert für Option format [maildir]: mdbox -Neuer Wert für Option subscribe [True]: -Neuer Wert für Option root [Maildir]: mdbox -.fi -.\" ------------------------------------ -.SS getuser (gu) -.BI "vmm getuser" " uid" -.PP -Wenn nur der -.I uid -eines Benutzers vorhanden ist, zum Beispiel aus der Prozessliste, kann mit -dem Unterbefehl -.B getuser -die E\-Mail\-Adresse des Benutzers ermittelt werden. -.PP -Beispiel: -.PP -.nf -.B vmm getuser 79876 -Konto Informationen -------------------- - UID............: 79876 - GID............: 70704 - Address........: a.user@example.com -.fi -.\" ------------------------------------ -.SS help (h) -.B vmm help -.RI [ subcommand ] -.PP -Gibt ein Liste aller vorhandenen Unterbefehle mit einer kurzen Beschreibung -aus. -Wurde ein -.I subcommand -angegeben, wird Hilfe zu diesem Unterbefehl ausgegeben. -Danach wird -.B vmm -beendet. -.\" ------------------------------------ -.SS listdomains (ld) -.B vmm listdomains -.RI [ pattern ] -.PP -Dieser Unterbefehl listet alle angelegten Domains auf. -Allen Domains wird ein Präfix vorangestellt. -Entweder ein `[+]', falls es sich um eine primäre Domain handelt, oder ein -`[-]', falls es sich um eine Alias\-Domain handelt. -Die Ausgabe kann reduziert werden, indem ein optionales Muster angegeben -wird. -.PP -Um eine Wildcard\-Suche durchzuführen kann das %\-Zeichen am Anfang -und/oder Ende des Musters verwendet werden. -.PP -Beispiel: -.PP -.nf -.B vmm listdomains %example% -Übereinstimmende Domains ------------------------- - [+] example.com - [\-] e.g.example.com - [\-] example.name - [+] example.org - [+] sales.example.com -.fi -.\" ------------------------------------ -.SS listaddresses (ll) -.B vmm listaddresses -.RI [ pattern ] -.PP -Verwenden Sie diesen Unterbefehl, um alle Adressen anzuzeigen. -Einträge regulärer Domains werden mit einem '+' gekennzeichnet, Einträge -von Alias-Domains mit einem '-'. Zudem wird jedem Eintrag ein 'u', 'a', -oder 'r' vorangestellt, welche den Eintrag als Benutzerkonto, Alias oder -Relocated User identifizieren. -.PP -Mit dem optionalen Muster können Sie die Ausgabe einschränken. Akzeptiert -wird entweder eine Domain oder ein SQL-Muster (% als Wildcard). -.PP -Beispiel: -.PP -.nf -.B vmm listaddresses example.com -.B vmm listaddresses %master@% -.\" ------------------------------------ -.SS listaliases (la) -.B vmm listaliases -.RI [ pattern ] -.PP -Verwenden Sie diesen Unterbefehl, um alle Aliase anzuzeigen. Reguläre -Aliase werden mit einem '+' gekennzeichnet, Aliase in Alias-Domains mit -einem '-'. -.PP -Mit dem optionalen Muster können Sie die Ausgabe einschränken. Akzeptiert -wird entweder eine Domain oder ein SQL-Muster (% als Wildcard). -.PP -Beispiel: -.PP -.nf -.B vmm listaliases example.com -.B vmm listaliases %master@% -.\" ------------------------------------ -.SS listrelocated (lr) -.B vmm listrelocated -.RI [ pattern ] -.PP -Verwenden Sie diesen Unterbefehl, um alle Relocated Users anzuzeigen. -Einträge regulärer Domains werden mit einem '+' gekennzeichnet, Einträge -von Alias-Domains mit einem '-'. -.PP -Mit dem optionalen Muster können Sie die Ausgabe einschränken. Akzeptiert -wird entweder eine Domain oder ein SQL-Muster (% als Wildcard). -.PP -Beispiel: -.PP -.nf -.B vmm listrelocated example.com -.B vmm listrelocated %master@% -.\" ------------------------------------ -.SS listusers (lu) -.B vmm listusers -.RI [ pattern ] -.PP -Verwenden Sie diesen Unterbefehl, um alle Benutzerkonten anzuzeigen. -Reguläre Benutzerkonten werden mit einem '+' gekennzeichnet, Benutzerkonten -in Alias-Domains mit einem '-'. -.PP -Mit dem optionalen Muster können Sie die Ausgabe einschränken. Akzeptiert -wird entweder eine Domain oder ein SQL-Muster (% als Wildcard). -.PP -Beispiel: -.PP -.nf -.B vmm listusers example.com -.B vmm listusers %master@% -.\" ------------------------------------ -.SS listpwschemes (lp) -.B vmm listpwschemes -.PP -Dieser Unterbefehl listet alle unterstützte Passwort\-Schemen, die als Wert -für -.I misc.password_scheme -in der -.I vmm.cfg -verwendet werden können. -Die Ausgabe variiert, je nach eingesetzter Dovecot Version und der libc des -Systems. -.br -Sollte Ihre Dovecot\-Installation nicht zu alt sein, werden zusätzlich -die verwendbaren Encoding\-Suffixe ausgegeben. -Eines dieser Suffixe kann an das Passwort\-Schema angefügt werden. -.PP -Beispiel: -.PP -.nf -.B vmm listpwschemes -Verfügbare Passwort-Schemata ----------------------------- - CRYPT SHA512-CRYPT LDAP-MD5 DIGEST-MD5 SHA256 SHA512 SSHA512 - SKEY SSHA NTLM RPA MD5-CRYPT HMAC-MD5 SHA1 PLAIN SHA CRAM-MD5 - SSHA256 MD5 LANMAN CLEARTEXT PLAIN-MD5 PLAIN-MD4 OTP SMD5 - SHA256-CRYPT - -Verwendbare Encoding-Suffixe ----------------------------- - .B64 .BASE64 .HEX -.fi -.\" ------------------------------------ -.SS version (v) -.B vmm version -.PP -Gibt Versions\- und Copyright\-Informationen zu -.B vmm -aus. -Danach wird -.B vmm -beendet. -.\" ----------------------------------------------------------------------- -.SH DOMAIN UNTERBEFEHLE -.SS domainadd (da) -.B vmm domainadd -.IR fqdn " [" transport ] -.PP -Fügt eine neue Domain in die Datenbank ein und erstellt das -Domain\-Verzeichnis. -.PP -Wurde das optional Argument -.I transport -angegeben, ersetzt der angegebene Transport den konfigurierten Transport -.RI ( misc.transport ") aus " vmm.cfg . -Der angegebene -.I transport -ist der Vorgabe\-Transport für alle Konten, die dieser Domain zugeordnet -werden. -.PP -Konfigurationsbezogenes Verhalten: -.RS -.TP -.I domain.auto_postmaster -Wenn diese Option den Wert -.B true -(Vorgabe) hat, wird -.B vmm -nach erfolgreichem Anlegen der Domain auch das Konto für -.BI postmaster@ fqdn -erstellen. -.TP -.I account.random_password -Sollte dieser Option ebenfalls der Wert -.B true -zugewiesen sein, wird ein zufällig generiertes Passwort für den -Postmaster\-Account gesetzt und auf stdout ausgegeben. -.RE -.PP -Beispiele: -.PP -.nf -.B vmm domainadd support.example.com smtp:[mx1.example.com]:2025 -Konto für postmaster@support.example.com wird angelegt -Neues Passwort eingeben: -Neues Passwort wiederholen: -.B vmm cs account.random_password true -.B vmm domainadd vertrieb.example.com -Konto für postmaster@vertrieb.example.com wird angelegt -Erzeugtes Passwort: YoG3Uw*5aH -.fi -.\" ------------------------------------ -.SS domaindelete (dd) -.BI "vmm domaindelete " fqdn -.RB [ force ] -.PP -Dieser Unterbefehl löscht die Domain mit dem angegebenen -.IR fqdn . -.PP -Sollten der zu löschenden Domain Konten, Aliase und/oder Relocated User -zugeordnet sein, wird -.B vmm -die Ausführung des Befehls mit einer entsprechenden Fehlermeldung beenden. -Sollten Sie sich Ihres Vorhabens sicher sein, so kann optional das -Schlüsselwort -.B force -angegeben werden. -.PP -Sollten Sie wirklich immer wissen was Sie tun, so editieren Sie Ihre -.I vmm.cfg -und setzen den Wert der Option -.I domain.force_deletion -auf -.BR true . -Dann werden Sie zukünftig beim Löschen von Domains nicht mehr wegen -vorhanden Konten, Aliase und/oder Relocated User gewarnt. -.\" ------------------------------------ -.SS domaininfo (di) -.B vmm domaininfo -.IR fqdn \ [ details ] -.PP -Dieser Unterbefehl zeigt Informationen zur Domain mit dem angegebenen -.I fqdn -an. -.PP -Um detaillierte Informationen über die Domain zu erhalten, kann das -optionale Argument -.I details -angegeben werden. -Ein möglicher Wert für -.I details -kann eines der folgenden sechs Schlüsselwörter sein: -.RS -.TP 13 -.B accounts -um alle eingerichteten Konten aufzulisten -.TP -.B aliasdomains -um alle zugeordneten Alias\-Domains aufzulisten -.TP -.B aliases -um alle vorhandenen Alias\-Adressen aufzulisten -.TP -.B catchall -um alle Catch\-all\-Ziele aufzulisten -.TP -.B relocated -um alle Adressen der Relocated Users aufzulisten -.TP -.B full -um alle oben genannten Informationen aufzulisten -.RE -.PP -Beispiel: -.PP -.nf -.B vmm domaininfo sales.example.com -Domain Informationen --------------------- - Domain Name......: sales.example.com - GID..............: 70708 - Domain Directory.: /srv/mail/c/70708 - Quota Limit/User.: Storage: 500,00 MiB; Messages: 10.000 - Active Services..: IMAP SIEVE - Transport........: lmtp:unix:private/dovecot-lmtp - Alias Domains....: 0 - Accounts.........: 1 - Aliases..........: 0 - Relocated........: 0 - Catch-All Dests..: 1 -.fi -.\" ------------------------------------ -.SS domainquota (dq) -.B vmm domainquota -.IR "fqdn storage" " [" messages ] -.RB [ force ] -.PP -Dieser Unterbefehl wird verwendet, um für die Konten der Domain ein neues -Quota\-Limit festzulegen. -.PP -Standardmäßig gilt für Konten das Quota\-Limit der -.IR vmm.cfg " (" domain.quota_bytes " und " domain.quota_messages ). -Das neue Quota\-Limit gilt für für alle bestehenden Konten, die nicht selbst -ein Quota\-Limit definieren. Soll das neue Quota\-Limit auch für Konten mit -eigenen Limiten angewendet werden, so ist das optionale Schlüsselwort -.B force -anzugeben. -.br -Wenn der Wert für das Argument -.I messages -ausgelassen wurde, wird der Vorgabewert -.B 0 -(null) als Anzahl von Nachrichten angewendet werden. -.PP -Beispiel: -.PP -.nf -.B vmm domainquota example.com 1g force -.fi -.\" ------------------------------------ -.SS domainservices (ds) -.B vmm domainservices -.IR fqdn " [" "service ..." ] -.RB [ force ] -.PP -Um festzulegen, welche Services für die Anwender der Domain \(em mit dem -angegebenen -.I fqdn -\(em nutzbar sein sollen, wird dieser Unterbefehl verwendet. -.PP -Der Zugriff auf alle genannten Services wird den Anwender gestattet. -Der Zugriff auf nicht genannte Services wird verweigert werden. -Verwendbare -.IR service \-Namen -sind: -.BR imap ", " pop3 ", " sieve " und " smtp . -.br -Wird das Schlüsselwort -.B force -angegeben, so werden alle kontospezifischen Einstellungen gelöscht und es -gelten fortan die Service\-Einstellungen der Domain für alle Konten. Ohne -dieses Schlüsselwort gelten die neuen Einstellungen nur für Konten, bei denen -die Service\-Einstellungen nicht individuell geändert wurden. -.\" ------------------------------------ -.SS domaintransport (dt) -.BI "vmm domaintransport" " fqdn transport" -.RB [ force ] -.PP -Ein neuer -.I transport -für die Domain mit dem angegebenen -.I fqdn -kann mit diesem Unterbefehl festgelegt werden. -.PP -Wird das Schlüsselwort -.B force -angegeben, so werden alle kontospezifischen Einstellungen gelöscht und es -gelten fortan die Transport\-Einstellungen der Domain für alle Konten. Ohne -dieses Schlüsselwort gelten die neuen Einstellungen nur für Konten, bei denen -die Transport\-Einstellungen nicht individuell geändert wurden. -.PP -Beispiel: -.PP -.nf -.B vmm domaintransport support.example.com dovecot: -.fi -.\" ------------------------------------ -.SS domainnote (do) -.BI "vmm domainnote" " fqdn" -.RI [ note ] -.PP -Mit diesem Unterbefehl kann eine Domain mit einer Notiz versehen werden. Um -die Notiz wieder zu löschen, läßt man sie einfach weg. -.PP -Beispiel: -.PP -.nf -.B vmm do example.com Gehört Robert -.fi -.\" ----------------------------------------------------------------------- -.SH ALIAS\-DOMAIN UNTERBEFEHLE -Eine Alias\-Domain ist ein Alias für eine Domain, die zuvor mit dem -Unterbefehl -.B domainadd -erstellt wurde. -Alle Konten, Aliase und Relocated Users der Domain sind ebenfalls unter der -Alias\-Domain verfügbar. -.br -Im Folgenden wird angenommen, example.net sei ein Alias für example.com. -.PP -Postfix wird nicht erst fälschlicherweise E\-Mails für -unbekannten.user@example.net annehmen und später an den \(em oftmals -gefälschten \(em Absender bouncen. -Postfix wird E\-Mails an unbekannte Empfänger sofort ablehnen. -.br -Dieses Verhalten ist sichergestellt, solange die empfohlenen -Datenbankabfragen in -.I $config_directory/pgsql\-*.cf -konfiguriert sind. -.\" ------------------------------------ -.SS aliasdomainadd (ada) -.BI "vmm aliasdomainadd" " fqdn destination" -.PP -Dieser Unterbefehl legt die Alias\-Domain -.RI ( fqdn ) -als Alias für eine bestehende Domain -.RI ( destination ") an." -.PP -Beispiel: -.PP -.nf -.B vmm aliasdomainadd example.net example.com -.fi -.\" ------------------------------------ -.SS aliasdomaindelete (add) -.BI "vmm aliasdomaindelete" " fqdn" -.PP -Verwenden Sie diesen Unterbefehl, um die Alias\-Domain -.I fqdn -zu löschen. -.PP -Beispiel: -.PP -.nf -.B vmm aliasdomaindelete e.g.example.com -.fi -.\" ------------------------------------ -.SS aliasdomaininfo (adi) -.BI "vmm aliasdomaininfo" " fqdn" -.PP -Dieser Unterbefehl gibt Informationen darüber aus, welcher Domain die -Alias\-Domain -.I fqdn -aktuell zugeordnet ist. -.PP -Beispiel: -.PP -.nf -.B vmm adi example.net -Alias\-Domain Informationen --------------------------- - Die Alias\-Domain example.net gehört zu: - * example.com -.fi -.\" ------------------------------------ -.SS aliasdomainswitch (ads) -.BI "vmm aliasdomainswitch" " fqdn destination" -.PP -Wenn Sie die bereits vorhandene Alias\-Domain -.I fqdn -einer anderen Ziel\-Domain zuordnen wollen, verwenden Sie diesen -Unterbefehl. -.PP -Beispiel: -.PP -.nf -.B vmm aliasdomainswitch example.net example.org -.fi -.\" ----------------------------------------------------------------------- -.SH KONTO UNTERBEFEHLE -.SS useradd (ua) -.B vmm useradd -.IR address " [" password ] -.PP -Mit diesem Unterbefehl wird ein neues Konto für die angegebene Adresse -angelegt. -.PP -Wurde kein Passwort angegeben wird -.B vmm -dieses im interaktiven Modus erfragen. -Falls kein Passwort angegeben wurde und -.I account.random_password -den Wert -.B true -hat, wird -.B vmm -ein zufälliges Passwort generieren und auf stdout ausgeben, nachdem das -Konto angelegt wurde. -.PP -Beispiele: -.PP -.nf -.B vmm ua d.user@example.com \(dqA 5ecR3t P4s5\(rs/\(rs/0rd\(dq -.B vmm useradd e.user@example.com -Neues Passwort eingeben: -Neues Passwort wiederholen: -.fi -.\" ------------------------------------ -.SS userdelete (ud) -.BI "vmm userdelete" " address" -.RB [ force ] -.PP -Verwenden Sie diesen Unterbefehl, um das Konto mit der angegebenen Adresse -zu löschen. -.PP -Sollte es einen oder mehrere Aliase geben, deren Ziel\-Adresse mit der -Adresse des zu löschenden Kontos identisch ist, wird -.B vmm -die Ausführung des Befehls mit einer entsprechenden Fehlermeldung beenden. -Um dieses zu umgehen, kann das optionale Schlüsselwort -.B force -angegebenen werden. -.\" ------------------------------------ -.SS userinfo (ui) -.B "vmm userinfo" -.IR address " [" details ] -.PP -Dieser Unterbefehl zeigt einige Informationen über das Konto mit der -angegebenen Adresse an. -.PP -Wurde das optionale Argument -.I details -angegeben, werden weitere Informationen ausgegeben. -Mögliche Werte für -.I details -sind: -.RS -.TP 8 -.B aliases -um alle Alias\-Adressen, mit dem Ziel -.IR address , -aufzulisten -.TP -.B du -um zusätzlich die Festplattenbelegung des Mail\-Verzeichnisses eines Kontos -anzuzeigen. -Soll die Festplattenbelegung jedes Mal mit der -.B userinfo -ermittelt werden, ist in der -.I vmm.cfg -der Wert der Option -.I account.disk_usage -auf -.B true -zu setzen. -.TP -.B full -um alle oben genannten Informationen anzuzeigen -.RE -.PP -Beispiel: -.PP -.nf -.B vmm userinfo d.user@example.com -Konto Informationen -------------------- - Address..........: d.user@example.com - Name.............: None - UID..............: 79881 - GID..............: 70704 - Home.............: /srv/mail/2/70704/79881 - Mail_Location....: mdbox:~/mdbox - Quota Storage....: [ 0,00%] 0/500,00 MiB - Quota Messages...: [ 0,00%] 0/10.000 - Transport........: lmtp:unix:private/dovecot-lmtp - SMTP.............: deaktiviert - POP3.............: deaktiviert - IMAP.............: aktiviert - SIEVE............: aktiviert -.fi -.\" ------------------------------------ -.SS username (un) -.BI "vmm username" " address" -.RI [ name ] -.PP -Der bürgerliche Name des Kontoinhabers mit der angegebenen Adresse kann mit -diesem Unterbefehl gesetzt/aktualisiert werden. -.PP -Wird kein -.I name -übergeben, so wird der Wert in den Kontoinformationen gelöscht. -.PP -Beispiel: -.PP -.nf -.B vmm username d.user@example.com \(dqJohn Doe\(dq -.fi -.\" ------------------------------------ -.SS userpassword (up) -.BI "vmm userpassword" " address" -.RI [ password ] -.PP -Das Passwort eines Kontos kann mit diesem Unterbefehl aktualisiert werden. -.PP -Wurde kein Passwort angegeben, wird -.B vmm -dieses im interaktiven Modus erfragen. -.PP -Beispiel: -.PP -.nf -.B vmm up d.user@example.com \(dqA |\(rs/|0r3 5ecur3 P4s5\(rs/\(rs/0rd?\(dq -.fi -.\" ------------------------------------ -.SS usernote (uo) -.BI "vmm usernote" " address" -.RI [ note ] -.PP -Mit diesem Unterbefehl kann ein Konto mit einer Notiz versehen werden. Um die -Notiz wieder zu löschen, läßt man sie einfach weg. -.PP -Beispiel: -.PP -.nf -.B vmm uo d.user@example.com Wird nur bis Ende Mai 2012 gebraucht -.fi -.\" ------------------------------------ -.SS userquota (uq) -.BI "vmm userquota" " address storage" -.RI [ messages ] -.PP -Um ein neues Quota\-Limit für das Konto mit der angegebenen Adresse -festzulegen, wird dieser Unterbefehl verwendet. -.PP -Wenn der Wert für das Argument -.I messages -ausgelassen wurde, wird der Vorgabewert -.B 0 -(null) als Anzahl von Nachrichten angewendet werden. -.PP -Anstelle der Limits, bewirkt das Wort -.BR domain , -dass die Limits des Kontos gelöscht wird und somit wieder der in der -Domain gespeicherte Wert für das Konto gilt. -.PP -Beispiel: -.PP -.nf -.B vmm userquota d.user@example.com 750m -.B vmm userquote d.user@example.com domain -.fi -.\" ------------------------------------ -.SS userservices (us) -.B vmm userservices -.IR address " [" "service ..." ] -.PP -Verwenden Sie diesen Unterbefehl, um einem Anwender den Zugriff auf die -genannten Services zu gestatten. -.PP -Der Zugriff auf alle nicht genannten Services wird dem Anwender, mit der -angegebenen Adresse, verwehrt werden. -.PP -Anstelle einer Liste, bewirkt das Wort -.BR domain , -dass die benutzerspezifische Liste gelöscht wird und somit wieder die in -der Domain gespeicherte Liste für das Konto gilt. -.PP -Beispiel: -.PP -.nf -.B vmm userservices d.user@example.com SMTP IMAP -.B vmm userservices d.user@example.com domain -.\" ------------------------------------ -.SS usertransport (ut) -.BI "vmm usertransport" " address transport" -.PP -Mit diesem Unterbefehl kann ein abweichender -.I transport -für das Konto mit der angegebenen Adresse bestimmt werden. -.PP -Wird als -.I transport -das Wort 'domain' übergeben, so wird der explizite Transport des Kontos -wieder gelöscht und der in der Domain gespeicherte Wert benutzt. -.PP -Beispiel: -.br -Angenommen, Sie wollen mit Dovecots -.BR dsync (1) -die E\-Mails vom Maildir\-Format ins mdbox\-Format konvertieren, dann -können Sie Postfix, über den Transport, darüber informieren, es später -nochmals zu versuchen. -.PP -.nf -.B vmm ut d.user@example.com \(dqretry:4.0.0 Mailbox being migrated\(dq -# Konvertieren der Mailbox … -# … danach den Transport auf den Domainwert setzen -.B vmm usertransport d.user@example.com domain -.fi -.\" ----------------------------------------------------------------------- -.SH ALIAS UNTERBEFEHLE -.SS aliasadd (aa) -.BI "vmm aliasadd" " address destination ..." -.PP -Mit diesem Unterbefehl werden neue Alias\-Adressen, mit einer oder mehren -.IR destination (en), -erstellt. -.PP -Innerhalb der Zieladresse werden die Zeichenketten -.IR %n , -.IR %d -und -.IR %= -durch den ursprünglichen lokalen Teil, die Domain bzw. die Emailadresse mit -'=' anstelle von '@' ersetzt. Dies ermöglicht z.B. in Verbindung mit -Alias\-Domains domain\-spezifische Empfänger. -.PP -Beispiele: -.PP -.nf -.B vmm aliasadd john.doe@example.com d.user@example.com -.B vmm aa support@example.com d.user@example.com e.user@example.com -.B vmm aa postmaster@example.com postmaster+%d@example.org -.fi -.\" ------------------------------------ -.SS aliasdelete (ad) -.BI "vmm aliasdelete" " address" -.RI [ destination " ...]" -.PP -Verwenden Sie diesen Unterbefehl um den Alias mit der angegebenen Adresse -zu löschen. -.PP -Wurden eine oder mehrere optionale -.I destination -Adressen angegeben, so werden nur diese -.IR destination s -vom angegebenen Alias entfernt. -.PP -Beispiel: -.PP -.nf -.B vmm aliasdelete support@example.com d.user@example.com -.fi -.\" ------------------------------------ -.SS aliasinfo (ai) -.BI "vmm aliasinfo" " address" -.PP -Informationen zum Alias mit der angegebenen Adresse können mit diesem -Unterbefehl ausgegeben werden. -.PP -Beispiel: -.PP -.nf -.B vmm aliasinfo support@example.com -Alias Informationen -------------------- - E\-Mails für support@example.com werden weitergeleitet an: - * e.user@example.com -.fi -.\" ----------------------------------------------------------------------- -.SH RELOCATED UNTERBEFEHLE -.SS relocatedadd (ra) -.BI "vmm relocatedadd" " address newaddress" -.PP -Um einen neuen Relocated User anzulegen kann dieser Unterbefehl verwendet -werden. -.PP -Dabei ist -.I address -die ehemalige Adresse des Benutzers, zum Beispiel b.nutzer@example.com, und -.I newaddress -die neue Adresse, unter der die/der Benutzer/in erreichbar ist. -.PP -Beispiel: -.PP -.nf -.B vmm relocatedadd b.nutzer@example.com b\-nutzer@firma.tld -.fi -.\" ------------------------------------ -.SS relocatedinfo (ri) -.BI "vmm relocatedinfo " address -.PP -Dieser Unterbefehl zeigt die neue Adresse des Relocated Users mit mit der -angegebenen Adresse. -.PP -Beispiel: -.PP -.nf -.B vmm relocatedinfo b.nutzer@example.com -Verschiebe\-Informationen ------------------------- - Der Benutzer »b.nutzer@example.com« wurde nach »b\-nutzer@firma.tld« verschoben -.fi -.\" ------------------------------------ -.SS relocateddelete (rd) -.BI "vmm relocateddelete " address -.PP -Mit diesem Unterbefehl kann der Relocated User mit der angegebenen Adresse -gelöscht werden. -.PP -Beispiel: -.PP -.nf -.B vmm relocateddelete b.nutzer@example.com -.fi -.\" ----------------------------------------------------------------------- -.SH CATCH\-ALL UNTERBEFEHLE -.SS catchalladd (caa) -.BI "vmm catchalladd" " fqdn destination ..." -.PP -Mit diesem Unterbefehl können für eine Domain Adressen definiert werden, an -die E\-Mails geleitet werden, die an nicht\-existente Adressen innerhalb -dieser Domains adressiert sind. -Diese Adressen \(dqfangen alle\(dq diese E\-Mails auf, es sei denn es -bestehen spezifischere Aliase, Mailboxen oder Relocated\-Einträge. -.PP -WARNUNG: Catch\-all Adressen können dazu führen, dass ein Mailserver von -Spam überflutet wird, da Spammer zuweilen gerne alle möglichen Emailadressen -ausprobieren und man auf einmal zig tausend Nachrichten gerichtet an -Adressen von abba@example.org bis zztop@example.org weitergeleitet bekommt. -.PP -Beispiel: -.PP -.nf -.B vmm catchalladd example.com b.nutzer@example.org -.fi -.\" ------------------------------------ -.SS catchallinfo (cai) -.BI "vmm catchallinfo " fqdn -.PP -Dieser Unterbefehl zeigt die für eine Domain definierten Catch\-all Aliase -an. -.PP -Beispiel: -.PP -.nf -.B vmm catchallinfo example.com -Catch-all Informationen ------------------------ - Nachrichten an unbekannte Adressen innerhalb der example.com Domäne werden - weitergeleitet an: - * b.nutzer@example.org -.fi -.\" ------------------------------------ -.SS catchalldelete (cad) -.BI "vmm catchalldelete " fqdn -.RI [ destination " ...]" -.PP -Mit diesem Unterbefehl werden Catch\-all Aliase einer Domain wieder -gelöscht, -entweder nur das/die angegebene(n) Alias(e), oder alle, wenn keine -.I destination -Adresse angegeben wurde. -.PP -Beispiel: -.PP -.nf -.B vmm catchalldelete example.com b.nutzer@example.org -.fi -.\" ----------------------------------------------------------------------- -.SH DATEIEN -.TP -.I /root/vmm.cfg -Wird verwendet, falls vorhanden. -.TP -.I /usr/local/etc/vmm.cfg -Wird verwendet, sollte obige Datei nicht gefunden werden. -.TP -.I /etc/vmm.cfg -Wird verwendet, falls die oben genannten Dateien nicht existieren. -.\" ----------------------------------------------------------------------- -.SH SIEHE AUCH -.BR dsync (1), -.BR transport (5), -.BR vmm.cfg (5) -.\" ----------------------------------------------------------------------- -.SH INTERNET RESSOURCEN -.TP -Homepage -http://vmm.localdomain.org/ -.TP -Projekt\-Seite -http://sf.net/projects/vmm/ -.TP -Bugtracker -https://bitbucket.org/pvo/vmm/issues -.\" ----------------------------------------------------------------------- -.SH COPYING -vmm und die dazugehörigen Manualseiten wurden von Pascal Volk <user+vmm AT -localhost.localdomain.org> geschrieben und sind unter den Bedingungen der -BSD Lizenz lizenziert. \ No newline at end of file diff -r 659c4476c57c -r b678a1c43027 man/de/man5/vmm.cfg.5 --- a/man/de/man5/vmm.cfg.5 Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,625 +0,0 @@ -.TH "VMM.CFG" "5" "2012-08-12" "vmm 0.6" "vmm" -.SH NAME -vmm.cfg \- Konfigurationsdatei für vmm -.\" ----------------------------------------------------------------------- -.SH ÜBERSICHT -vmm.cfg -.\" ----------------------------------------------------------------------- -.SH BESCHREIBUNG -.BR vmm (1) -liest seine Konfigurationsparameter aus der Datei -.IR vmm.cfg . -.PP -Die Konfigurationsdatei ist in mehrere Sektionen unterteilt. -Jede Sektion wird mit dem in eckigen Klammern -.RB ' [ "' und '" ] ' -eingefassten Namen der Sektion eingeleitet, gefolgt von -.RI ' Option " = " Wert ' -Einträgen. -.PP -Leerräume um das Gleichheitszeichen '=' und am Ende eines Wertes werden -ignoriert. -Leerzeilen und Zeilen, die mit einer '#' oder einem ';' anfangen, werden -ignoriert. -.PP -Jeder Wert ist von einem der folgenden Datentypen: -.PP -.TP 8 -.I Boolean -um festzulegen, ob etwas eingeschaltet/aktiviert (true) oder -ausgeschaltet/deaktiviert (false) ist. -.br -Mögliche Werte für -.I true -sind: -.BR 1 , " yes" , " true" " und " on . -.br -Mögliche Werte für -.I false -sind: -.BR 0 , " no" , " false" " und " off . -.TP -.I Int -eine Integer\-Zahl, geschrieben ohne eine gebrochene oder dezimale -Komponente. -.br -Beispielsweise -.BR 1 , " 50" " oder " 321 -sind Integer\-Zahlen. -.TP -.I String -eine Folge von Buchstaben und Zahlen. -.br -Zum Beispiel: -.RB ' Wort "', '" "Hallo Welt" "' oder '" /usr/bin/strings ' -.PP -Die meisten Optionen haben einen Vorgabewert. -Dieser ist nach dem Namen der Option in Klammern angegebenen. -Um den Vorgabewert einer Option zu verwenden, wird die entsprechende Zeile -entweder mit -.BR # " oder " ; -auskommentiert oder die Zeile wird einfach aus der -.I vmm.cfg -entfernt. -.PP -Eine minimale -.I vmm.cfg -könnte so aussehen: -.PP -.nf -[database] -user = ich -pass = xxxxxxxx - -[misc] -dovecot_version = 1.2.16 -.fi -.\" ----------------------------------------------------------------------- -.SH SUCHREIHENFOLGE -Standardmäßig sucht -.BR vmm (1) -die -.I vmm.cfg -in folgenden Verzeichnissen, in der angegebenen Reihenfolge: -.RS -.PD 0 -.TP -.I -/root -.TP -.I -/usr/local/etc -.TP -.I -/etc -.PD -.RE -.PP -Die zuerst gefundene Datei wird verwendet. -.\" ----------------------------------------------------------------------- -.SH SEKTION ACCOUNT -Die Optionen der Sektion -.B account -legen Konto\-spezifische Einstellungen fest. -.SS account.delete_directory -.BR delete_directory " (Vorgabe: false) :" -.I Boolean -.PP -Bestimmt das Verhalten von -.BR vmm (1) -beim Löschen eines Kontos (userdelete). -Wenn der Wert dieser Option -.I true -ist, wird das Home\-Verzeichnis des zu löschenden Anwenders rekursiv -gelöscht. -.\" ------------------------------------ -.SS account.directory_mode -.BR directory_mode " (Vorgabe: 448) :" -.I Int -.PP -Zugriffsbits des Home\-Verzeichnisses, sowie aller enthaltenen -Verzeichnisse, in Dezimal\-Schreibweise (Basis 10). -.br -Beispiel: 'drwx\-\-\-\-\-\-' \(-> oktal 0700 \(-> dezimal 448 -.\" ------------------------------------ -.SS account.disk_usage -.BR disk_usage " (Vorgabe: false) :" -.I Boolean -.PP -Legt fest, ob die Festplattenbelegung des Maildirs eines Benutzers jedes -Mal mit -.BR du (1) -ermittelt und mit den Konto\-Informationen ausgegeben werden soll. -.PP -Bei umfangreichen Maildirs kann das langsam sein. -Falls Sie Quotas aktiviert haben, wird der -.BR vmm\-Unterbefehl -userinfo ebenfalls die aktuelle Quota\-Nutzung des Kontos mit ausgegeben. -Sie können auch eines der optionalen Argumente -.BR du " oder " full -an userinfo übergeben, um sich die aktuelle Festplattenbelegung anzeigen zu -lassen. -.\" ------------------------------------ -.SS account.password_length -.BR password_length " (Vorgabe: 8) :" -.I Int -.PP -Diese Option legt die Anzahl der Zeichen für automatisch erzeugte -Passwörter fest. -Alle Werte kleiner als 8 werden auf 8 erhöht. -.\" ------------------------------------ -.SS account.random_password -.BR random_password " (Vorgabe: false) :" -.I Boolean -.PP -Mit dieser Option wird bestimmt, ob -.BR vmm (1) -ein zufälliges Passwort generieren soll, wenn kein Passwort an den -Unterbefehl useradd übergeben wurde. -Ist der Wert dieser Option -.IR false , -wird -.B vmm -Sie auffordern, ein Passwort für den neuen Account einzugeben. -.PP -Sie können die Länge für automatisch generierte Passwörter mit der Option -.I account.password_length -konfigurieren. -.\" ----------------------------------------------------------------------- -.SH SEKTION BIN -In der -.BR bin \-Sektion -werden die Pfade zu den von -.BR vmm (1) -benötigten Binaries angegeben. -.SS bin.dovecotpw -.BR dovecotpw " (Vorgabe: /usr/sbin/dovecotpw) :" -.I String -.PP -Der absolute Pfad zum dovecotpw Binary. -Geben Sie den absoluten Pfad zum -.BR doveadm (1) -Binary an, falls Sie Dovecot v2.0 verwenden. -.PP -Dieses Binary wird zur Hash\-Erzeugung verwendet, wenn -.I misc.password_scheme -einen der nachfolgenden Werte hat: 'CRAM\-MD5', 'HMAC\-MD5', 'LANMAN', -\(aqOTP', 'RPA' oder 'SKEY'. -Dieses Binary wird auch benötigt, wenn Ihre Python\-Installation einen der -folgenden Hash\-Algorithmen nicht unterstützt: -.IP \(bu 4 -md4: (hashlib + OpenSSL oder PyCrypto) verwendet für die Passwort\-Schemen: -\(aqPLAIN\-MD4' und 'NTLM' -.IP \(bu -sha256: (hashlib oder PyCrypto \(>= 2.1.0alpha1) verwendet für die -Passwort\-Schemen: 'SHA256' und 'SSHA256' -.IP \(bu -sha512: (hashlib) verwendet für die Passwort\-Schemen: 'SHA512' und -\(aqSSHA512' -.PP -Das -.BR doveadm (1) -Binary wird auch gebraucht, um die INBOX und zusätzliche Mailboxen -.RI ( mailbox.folders ) -für einen neuen Account zu erstellen, wenn die Option -.I mailbox.format -den Wert -.BR mdbox " oder " sdbox -hat. -.\" ------------------------------------ -.SS bin.du -.BR du " (Vorgabe: /usr/bin/du) :" -.I String -.PP -Der absolute Pfad zu -.BR du (1). -Dieses Binary wird verwendet, wenn die Festplattenbelegung eines Kontos -ermittelt wird. -.\" ------------------------------------ -.SS bin.postconf -.BR postconf " (Vorgabe: /usr/sbin/postconf) :" -.I String -.PP -Der absolute Pfad zu Postfix' -.BR postconf (1). -Dieses Binary wird verwendet, wenn -.BR vmm (1) -diverse Postfix\-Einstellungen prüft, zum Beispiel das -.IR virtual_alias_expansion_limit . -.\" ----------------------------------------------------------------------- -.SH SEKTION DATABASE -Die -.BR database \-Sektion -wird verwendet, um die für den Datenbankzugriff erforderlichen Optionen -festzulegen. -.SS database.host -.BR host " (Vorgabe: localhost) :" -.I String -.PP -Der Hostname oder die IP\-Adresse des Datenbankservers. -.\" ------------------------------------ -.SS database.module -.BR module " (Vorgabe: psycopg2) :" -.I String -.PP -Das für den Datenbankzugriff zu verwendende Python PostgreSQL Adapter -Modul. -Unterstützte Module sind -.BR psycopg2 " und " pyPgSQL . -.\" ------------------------------------ -.SS database.name -.BR name " (Vorgabe: mailsys) :" -.I String -.PP -Der Name der zu verwendenden Datenbank. -.\" ------------------------------------ -.SS database.pass -.BR pass " (Vorgabe: " None ") :" -.I String -.PP -Das Passwort des Datenbank\-Benutzers. -.\" ------------------------------------ -.SS database.port -.BR port " (Vorgabe: 5432) :" -.I Int -.PP -Der TCP\-Port, auf dem der Datenbankserver Verbindungen annimmt. -.\" ------------------------------------ -.SS database.sslmode -.BR sslmode " (Vorgabe: prefer) :" -.I String -.PP -Bestimmt, ob und mit welcher Priorität eine SSL\-Verbindung mit dem -Datenbankserver ausgehandelt wird. -Mögliche Werte sind: -.BR disabled ", " allow ", " prefer ", " require ", " verify\-ca " und " -.BR verify\-full . -Die Modi -.BR verify\-ca " und " verify\-full -stehen seit PostgreSQL 8.4 zur Verfügung. -.PP -Diese Option wird ignoriert, wenn das -.I database.module -.B pyPgSQL -verwendet wird. -.\" ------------------------------------ -.SS database.user -.BR user " (Vorgabe: " None ") :" -.I String -.PP -Der Name des Datenbank\-Benutzers. -.\" ----------------------------------------------------------------------- -.SH SEKTION DOMAIN -In der -.BR domain \-Sektion -werden Domain\-spezifische Einstellungen hinterlegt. -.PP -Das Quota\-Limit (quota_bytes und quota_messages), Service\-Einstellungen -(imap, pop3, sieve und smtp) und der Transport werden angewendet, wenn -eine Domain angelegt wird. -Um die Einstellungen einer vorhandenen Domain zu ändern, verwenden Sie -einen der folgenden -.BR vmm (1) -Unterbefehle: -.PP -.TP -.B domainquota -um das Quota\-Limit einer Domain zu ändern -.TP -.B domainservices -um einer Domain einen abweichenden Satz von nutzbaren Services zuzuweisen -.TP -.B domaintransport -um einen neuen Vorgabe\-Transport für eine Domain festzulegen -.PP -Wenn ein Account angelegt wird, erbt er alle Einstellungen von der Domain, -zu der er hinzugefügt wird. -Abweichende Einstellungen für einen vorhandenen Account nehmen Sie mit -einem der Unterbefehle -.BR userquota ", " userservices " und " usertransport -vor. -.\" ------------------------------------ -.SS domain.auto_postmaster -.BR auto_postmaster " (Vorgabe: true) :" -.I Boolean -.PP -Ist der Wert dieser Option -.IR true , -wird -.BR vmm (1) -beim Anlegen einer Domain (domainadd) automatisch einen postmaster\-Account -erstellen. -.\" ------------------------------------ -.SS domain.delete_directory -.BR delete_directory " (Vorgabe: false) :" -.I Boolean -.PP -Legt fest, ob beim Löschen einer Domain (domaindelete) das Verzeichnis der -zu löschenden Domain, inklusive aller Anwender\-Verzeichnisse, rekursiv -gelöscht werden soll. -.\" ------------------------------------ -.SS domain.directory_mode -.BR directory_mode " (Vorgabe: 504) :" -.I Int -.PP -Zugriffsbits des Domain\-Verzeichnisses in Dezimal\-Schreibweise -(Basis 10). -.br -Beispiel: 'drwxrwx\-\-\-' \(-> oktal 0770 \(-> dezimal 504 -.\" ------------------------------------ -.SS domain.force_deletion -.BR force_deletion " (Vorgabe: false) :" -.I Boolean -.PP -Erzwingt das Löschen aller zugeordneten Konten und Aliase beim Löschen -einer Domain (domaindelete). -.\" ------------------------------------ -.SS domain.imap -.BR imap " (Vorgabe: true) :" -.I Boolean -.PP -Legt fest, ob sich neu angelegte Benutzer per IMAP anmelden können sollen. -.\" ------------------------------------ -.SS domain.pop3 -.BR pop3 " (Vorgabe: true) :" -.I Boolean -.PP -Legt fest, ob sich neu angelegte Benutzer per POP3 anmelden können sollen. -.\" ------------------------------------ -.SS domain.quota_bytes -.BR quota_bytes " (Vorgabe: 0) :" -.I String -.PP -Quota Limit in Bytes. -0 bedeutet unbegrenzt. -Dieses Limit wird beim Anlegen von Domains angewendet. -.PP -Der Wert dieser Option kann als Integer\-Wert, zum Beispiel -.B 20480 -geschrieben werden. -Es ist auch möglich dem Wert eines der folgenden -Suffixe anzuhängen: -.BR b " (Bytes), " k " (Kilobytes), " M " (Megabytes) oder " G -(Gigabytes). -.br -1024 entspricht 1024b oder 1k. -.\" ------------------------------------ -.SS domain.quota_messages -.BR quota_messages " (Vorgabe: 0) :" -.I Int -.PP -Quota Limit als Anzahl von Nachrichten. -0 bedeutet unbegrenzt. -Dieses Limit wird beim Anlegen neuer Domains angewendet. -.\" ------------------------------------ -.SS domain.sieve -.BR sieve " (Vorgabe: true) :" -.I Boolean -.PP -Legt fest, ob sich neu angelegte Benutzer per SIEVE (ManageSieve) anmelden -können sollen. -.\" ------------------------------------ -.SS domain.smtp -.BR smtp " (Vorgabe: true) :" -.I Boolean -.PP -Legt fest, ob sich neu angelegte Benutzer per SMTP (SMTP AUTH) anmelden -können sollen. -.\" ------------------------------------ -.SS domain.transport -.BR transport " (Vorgabe: dovecot:) :" -.I String -.PP -Der Standard\-Transport aller neuen Domains. -Siehe auch: -.BR transport (5). -.\" ----------------------------------------------------------------------- -.SH SEKTION MAILBOX -In der -.BR mailbox \-Sektion -werden die für die Erstellung von Mailboxen erforderlichen Optionen -festgelegt. -Die INBOX wird in jedem Fall erstellt. -.SS mailbox.folders -.BR folders " (Vorgabe: Drafts:Sent:Templates:Trash) :" -.I String -.PP -Eine durch Doppelpunkte getrennte Liste mit Namen der zu erstellenden -Mailboxen. -Sollen keine zusätzlichen Mailboxen angelegt werden, ist dieser Option ein -einzelner Doppelpunkt -.RB (' : ') -als Wert zuzuweisen. -.PP -Sollen Verzeichnisse mit Unterverzeichnissen angelegt werden, ist ein -einzelner Punkt -.RB (' . ') -als Separator zu verwenden. -.PP -Sollen Mailboxen mit internationalisierten Namen erstellt werden (zum -Beispiel: 'Wysłane' oder 'Gelöschte Objekte'), ist der Name UTF\-8 kodiert -anzugeben. -.BR vmm (1) -wird die internationalisierten Mailboxnamen in eine modifizierten Variante -des UTF\-7\-Zeichensatzes (siehe auch: RFC 3501, Sektion 5.1.3) -konvertieren. -.\" ------------------------------------ -.SS mailbox.format -.BR format " (Vorgabe: maildir) :" -.I String -.PP -Das zu verwendende Mailbox\-Format für die Mailboxen der Benutzer. -Abhängig von der verwendeten Dovecot\-Version -.RI ( misc.dovecot_version ), -unterstützt -.BR vmm (1) -bis zu drei Formate: -.TP 8 -.B maildir -Dovecot \(>= v1.0.0 -.TP -.B mdbox -Dovecot \(>= v2.0.beta5 -.TP -.B sdbox -Dovecot \(>= v2.0.rc3 -.\" ------------------------------------ -.SS mailbox.root -.BR root " (Vorgabe: Maildir) :" -.I String -.PP -Name des Mailbox\-Wurzelverzeichnisses im Home\-Verzeichnis des jeweiligen -Benutzers. -Übliche Namen, je nach verwendetem -.IR mailbox.format , -sind -.BR Maildir ", " mdbox " or " sdbox . -.\" ------------------------------------ -.SS mailbox.subscribe -.BR subscribe " (Vorgabe: true) :" -.I Boolean -.PP -Wenn dieser Option der Wert -.B true -zugewiesen wurde, werden die, gemäß -.IR mailbox.folders , -erstellen Mailboxen in der subscriptions\-Datei des Benutzers gelistet. -Sollen die erstellen Mailboxen nicht nicht in der subscriptions\-Datei -gelistet werden, weisen Sie dieser Option den Wert -.B false -zu. -.\" ----------------------------------------------------------------------- -.SH SEKTION MISC -In der -.BR misc \-Sektion -werden Einstellungen für verschiedene Bereiche festgelegt. -.SS misc.base_directory -.BR base_directory " (Vorgabe: /srv/mail) :" -.I String -.PP -Alle Domain\-Verzeichnisse werden innerhalb dieses Basis\-Verzeichnisses -angelegt. -.\" ------------------------------------ -.SS misc.crypt_blowfish_rounds -.BR crypt_blowfish_rounds " (Vorgabe: 5) :" -.I Int -.PP -Anzahl der Verschlüsselungsdurchgänge für das -.I password_scheme -.BR BLF\-CRYPT . -.PP -Der Wert muss im Bereich von -.BR 4 " \- " 31 -liegen. -.\" ------------------------------------ -.SS misc.crypt_sha256_rounds -.BR crypt_sha256_rounds " (Vorgabe: 5000) :" -.I Int -.PP -Anzahl der Verschlüsselungdurchgänge für das -.I password_scheme -.BR SHA256\-CRYPT . -.PP -Der Wert muss im Bereich von -.BR 1000 " \- " 999999999 -liegen. -.\" ------------------------------------ -.SS misc.crypt_sha512_rounds -.BR crypt_sha512_rounds " (Vorgabe: 5000) :" -.I Int -.PP -Anzahl der Verschlüsselungdurchgänge für das -.I password_scheme -.BR SHA512\-CRYPT . -.PP -Der Wert muss im Bereich von -.BR 1000 " \- " 999999999 -liegen. -.\" ------------------------------------ -.SS misc.dovecot_version -.BR dovecot_version " (Vorgabe: " None ") :" -.I String -.PP -Die aktuell eingesetzte Dovecot\-Version. -(siehe: -.BR "dovecot \-\-version" ). - -Wenn das Kommando -.B dovecot \-\-version -zum Beispiel -.I 2.0.beta4 (8818db00d347) -ausgibt, ist dieser Option der Wert -.B 2.0.beta4 -zuzuweisen. -.\" ------------------------------------ -.SS misc.password_scheme -.BR password_scheme " (Vorgabe: CRAM\-MD5) :" -.I String -.PP -Das zu verwendende Passwort\-Schema. -Um eine Liste aller verwendbaren Passwort\-Schemen zu erhalten, führen Sie -das Kommando -.B vmm lp -aus. -.PP -Seit Dovecot \(>= v1.1.alpha1 ist es möglich, dem -.I password_scheme -ein Encoding\-Suffix anzufügen. -Unterstützte Encoding\-Suffixe: -.BR .b64 ", " .base64 " und " .hex . -Beispiel: PLAIN.BASE64 -.\" ----------------------------------------------------------------------- -.SH BEISPIEL -Eine Beispiel\-Konfiguration. -Alle Optionen, die nicht in der Konfigurationsdatei gelistet sind, haben -ihren Vorgabewert. -.PP -.nf -[account] -password_length = 10 -random_password = true - -[bin] -dovecotpw = /usr/bin/doveadm - -[database] -host = dbsrv8.example.net -pass = PY_SRJ}L/0p\-oOk -port = 5433 -sslmode = require -user = vmm - -[domain] -quota_bytes = 500M -quota_messages = 10000 -transport = lmtp:unix:private/dovecot\-lmtp - -[mailbox] -folders = Drafts:Sent:Templates:Trash:Lists.Dovecot:Lists.Postfix - -[misc] -crypt_sha512_rounds = 10000 -dovecot_version = 2.0.beta4 -password_scheme = SHA512\-CRYPT.hex -.fi -.\" ----------------------------------------------------------------------- -.SH SIEHE AUCH -.BR postconf (1), -.BR vmm (1), -.BR transport (5) -.\" ----------------------------------------------------------------------- -.SH INTERNET RESSOURCEN -.TP -Homepage -http://vmm.localdomain.org/ -.TP -Projekt\-Seite -http://sf.net/projects/vmm/ -.TP -Bugtracker -https://bitbucket.org/pvo/vmm/issues -.\" ----------------------------------------------------------------------- -.SH COPYING -vmm und die dazugehörigen Manualseiten wurden von Pascal Volk <user+vmm AT -localhost.localdomain.org> geschrieben und sind unter den Bedingungen der -BSD Lizenz lizenziert. \ No newline at end of file diff -r 659c4476c57c -r b678a1c43027 man/man1/vmm.1 --- a/man/man1/vmm.1 Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1065 +0,0 @@ -.TH "VMM" "1" "2012-09-27" "vmm 0.6" "vmm" -.SH NAME -vmm \- command line tool to manage email domains/accounts/aliases -.\" ----------------------------------------------------------------------- -.SH SYNOPSIS -.B vmm -.IR subcommand " [" "argument ..." ] -.\" ----------------------------------------------------------------------- -.SH DESCRIPTION -.B vmm -(a virtual mail manager) is the easy to use command line tool for -administrators and postmasters to manage (alias) domains, accounts, aliases -and relocated users. -It allows you to simply and quickly administer your mail server. -.br -It's designed for Dovecot and Postfix with a PostgreSQL backend. -.PP -Each -.I subcommand -has both a long and a short form. -The short form is shown enclosed in parentheses. -Both forms are case sensitive. -.PP -Most of the -.IR subcommand s -take one or more -.IR argument s. -.\" ----------------------------------------------------------------------- -.SH ARGUMENTS -.TP 12 -.I address -The complete e\-mail address -.RI ( local\-part @ fqdn ) -of an user account, alias address or relocated user. -.\" -------------------------- -.TP -.I destination -Is either an e\-mail -.I address -when used with -.IR "ALIAS SUBCOMMANDS" . -Or a -.I fqdn -when used with -.IR "ALIASDOMAIN SUBCOMMANDS" . -.\" -------------------------- -.TP -.I fqdn -The fully qualified domain name \- without the trailing dot \- of a domain -or alias domain. -.\" -------------------------- -.TP -.I messages -An integer value which specifies a quota limit in number of messages. -.B 0 -(zero) means unlimited \- no quota limit for the number of messages. -.\" -------------------------- -.TP -.I option -is the name of a configuration option, prefixed with the section name and a -dot. -For example: -.IB misc . transport -.br -All configuration options are described in -.BR vmm.cfg (5). -.\" -------------------------- -.TP -.I service -The name of a service, commonly used with Dovecot. -Supported services are: -.BR imap ", " pop3 ", " sieve " and " smtp . -.\" -------------------------- -.TP -.I storage -Specifies a quota limit in bytes. -One of the following prefixes can be appended to the integer value: -.BR b " (bytes), " k " (kilobytes), " M " (megabytes) or " G -(gigabytes). -.B 0 -(zero) means unlimited \- no quota limit in bytes. -.\" -------------------------- -.TP -.I transport -A transport for Postfix, written as: -.IB transport : -or -.IB transport :\c -.IR nexthop . -See -.BR transport (5) -for more details. -.\" ----------------------------------------------------------------------- -.SH GENERAL SUBCOMMANDS -.SS configget (cg) -.BI "vmm configget" " option" -.PP -This subcommand is used to display the actual value of the given -configuration -.IR option . -.PP -Example: -.PP -.nf -.B vmm configget misc.crypt_sha512_rounds -misc.crypt_sha512_rounds = 5000 -.fi -.\" ------------------------------------ -.SS configset (cs) -.B vmm configset -.I option value -.PP -Use this subcommand to set or update a single configuration option's value. -.I option -is the configuration option, -.I value -is the -.IR option 's -new value. -.IP Note: -This subcommand will create a new -.I vmm.cfg -without any comments. -Your current configuration file will be backed as -.IR vmm.cfg.bak . -.PP -Example: -.PP -.nf -.B vmm configget domain.transport -domain.transport = dovecot: -.B vmm configset domain.transport lmtp:unix:private/dovecot\-lmtp -.B vmm cg domain.transport -domain.transport = lmtp:unix:private/dovecot\-lmtp -.fi -.\" ------------------------------------ -.SS configure (cf) -.B vmm configure -.RI [ section ] -.PP -Starts the interactive configuration for all configuration sections. -.PP -In this process the currently set value of each option will be displayed in -square brackets. -If no value is configured, the default value of each option will be -displayed in square brackets. -Press the return key, to accept the displayed value. -.PP -If the optional argument -.I section -is given, only the configuration options from the given section will be -displayed and will be configurable. -The following sections are available: -.RS -.TP 10 -.B account -Account settings -.TP -.B bin -Paths to external binaries -.TP -.B database -Database settings -.TP -.B domain -Domain settings -.TP -.B mailbox -Mailbox settings -.TP -.B misc -Miscellaneous settings -.RE -.PP -All configuration options are described in -.BR vmm.cfg (5). -.IP Note: -This subcommand will create a new -.I vmm.cfg -without any comments. -Your current configuration file will be backed as -.IR vmm.cfg.bak . -.PP -Example: -.PP -.nf -.B vmm configure mailbox -Using configuration file: /usr/local/etc/vmm.cfg - -* Configuration section: `mailbox' -Enter new value for option folders [Drafts:Sent:Templates:Trash]: -Enter new value for option format [maildir]: mdbox -Enter new value for option subscribe [True]: -Enter new value for option root [Maildir]: mdbox -.fi -.\" ------------------------------------ -.SS getuser (gu) -.BI "vmm getuser" " uid" -.PP -If only the -.I uid -is available, for example from process list, the subcommand -.B getuser -will show the user's address. -.PP -Example: -.PP -.nf -.B vmm getuser 79876 -Account information -------------------- - UID............: 79876 - GID............: 70704 - Address........: a.user@example.com -.fi -.\" ------------------------------------ -.SS help (h) -.B vmm help -.RI [ subcommand ] -.PP -Prints a list of available subcommands with a short description to stdout. -When a -.I subcommand -was given, help for that -.I subcommand -will be displayed. -After this -.B vmm -exits. -.\" ------------------------------------ -.SS listdomains (ld) -.B vmm listdomains -.RI [ pattern ] -.PP -This subcommand lists all available domains. -All domain names will be prefixed either with `[+]', if the domain is a -primary domain, or with `[-]', if it is an alias domain name. -The output can be limited with an optional -.IR pattern . -.PP -To perform a wild card search, the % character can be used at the start -and/or the end of the -.IR pattern . -.PP -Example: -.PP -.nf -.B vmm listdomains %example% -Matching domains ----------------- - [+] example.com - [\-] e.g.example.com - [\-] example.name - [+] example.net - [+] example.org -.fi -.\" ------------------------------------ -.SS listaddresses (ll) -.B vmm listaddresses -.RI [ pattern ] -.PP -This command lists all defined addresses. Addresses belonging to -alias-domains are prefixed with a '-', addresses of regular domains with -a '+'. Additionally, the letters 'u', 'a', and 'r' indicate the type of -each address: user, alias and relocated respectively. -The output can be limited with an optional -.IR pattern . -.PP -To perform a wild card search, the % character can be used at the start -and/or the end of the -.IR pattern . -.PP -Example: -.PP -.nf -.B vmm listaddresses example.com -.B vmm listaddresses %master@% -.\" ------------------------------------ -.SS listaliases (la) -.B vmm listaliases -.RI [ pattern ] -.PP -This command lists all defined aliases. Aliases belonging to -alias-domains are prefixed with a '-', addresses of regular domains with -a '+'. -The output can be limited with an optional -.IR pattern . -.PP -To perform a wild card search, the % character can be used at the start -and/or the end of the -.IR pattern . -.PP -Example: -.PP -.nf -.B vmm listaliases example.com -.B vmm listaliases %master@% -.\" ------------------------------------ -.SS listrelocated (lr) -.B vmm listrelocated -.RI [ pattern ] -.PP -This command lists all defined relocated addresses. Relocated entries -belonging to alias-domains are prefixed with a '-', addresses of regular -domains with -a '+'. -The output can be limited with an optional -.IR pattern . -.PP -To perform a wild card search, the % character can be used at the start -and/or the end of the -.IR pattern . -.PP -Example: -.PP -.nf -.B vmm listrelocated example.com -.B vmm listrelocated %master@% -.\" ------------------------------------ -.SS listusers (lu) -.B vmm listusers -.RI [ pattern ] -.PP -This command lists all user accounts. User accounts belonging to -alias-domains are prefixed with a '-', addresses of regular -domains with -a '+'. -The output can be limited with an optional -.IR pattern . -.PP -To perform a wild card search, the % character can be used at the start -and/or the end of the -.IR pattern . -.PP -Example: -.PP -.nf -.B vmm listusers example.com -.B vmm listusers %master@% -.\" ------------------------------------ -.SS listpwschemes (lp) -.B vmm listpwschemes -.PP -This subcommand lists all password schemes which could be used in the -.I vmm.cfg -as value of the -.I misc.password_scheme -option. -The output varies, depending on the used Dovecot version and the system's -libc. -.br -When your Dovecot installation isn't too old, you will see additionally a -few usable encoding suffixes. -One of them can be appended to the password scheme. -.PP -Example: -.PP -.nf -.B vmm listpwschemes -Usable password schemes ------------------------ - CRYPT SHA512-CRYPT LDAP-MD5 DIGEST-MD5 SHA256 SHA512 SSHA512 - SKEY SSHA NTLM RPA MD5-CRYPT HMAC-MD5 SHA1 PLAIN SHA CRAM-MD5 - SSHA256 MD5 LANMAN CLEARTEXT PLAIN-MD5 PLAIN-MD4 OTP SMD5 - SHA256-CRYPT - -Usable encoding suffixes ------------------------- - .B64 .BASE64 .HEX -.fi -.\" ------------------------------------ -.SS version (v) -.B vmm version -.PP -Prints -.BR vmm 's -version and copyright information to stdout. -After this -.B vmm -exits. -.\" ----------------------------------------------------------------------- -.SH DOMAIN SUBCOMMANDS -.SS domainadd (da) -.B vmm domainadd -.IR fqdn " [" transport ] -.PP -Adds the new domain into the database and creates the domain directory. -.PP -If the optional argument -.I transport -is given, it will override the default transport -.RI ( domain.transport ") from " vmm.cfg . -The specified -.I transport -will be the default transport for all new accounts in this domain. -.PP -Configuration\-related behavior: -.RS -.TP -.I domain.auto_postmaster -When that option is set to -.BR true " (default) " vmm -will automatically create the postmaster account for the new domain and -prompt for -.BI postmaster@ fqdn\c -\(aqs password. -.TP -.I account.random_password -When the value of that option is also set to -.BR true ", " vmm -will automatically create the postmaster account for the new domain and -print the generated postmaster password to stdout. -.RE -.PP -Examples: -.PP -.nf -.B vmm domainadd support.example.com smtp:[mx1.example.com]:2025 -Creating account for postmaster@support.example.com -Enter new password: -Retype new password: -.B vmm cs account.random_password true -.B vmm domainadd sales.example.com -Creating account for postmaster@sales.example.com -Generated password: pLJUQ6Xg_z -.fi -.\" ------------------------------------ -.SS domaindelete (dd) -.BI "vmm domaindelete " fqdn -.RB [ force ] -.PP -This subcommand deletes the domain specified by -.IR fqdn . -.PP -If there are accounts, aliases and/or relocated users assigned to the given -domain, -.B vmm -will abort the requested operation and show an error message. -If you know, what you are doing, you can specify the optional keyword -.BR force . -.PP -If you really always know what you are doing, edit your -.I vmm.cfg -and set the option -.I domain.force_deletion -to -.BR true . -.\" ------------------------------------ -.SS domaininfo (di) -.B vmm domaininfo -.IR fqdn \ [ details ] -.PP -This subcommand shows some information about the given domain. -.PP -For a more detailed information about the domain the optional argument -.I details -can be specified. -A possible -.I details -value can be one of the following six keywords: -.RS -.TP 14 -.B accounts -to list the e\-mail addresses of all existing user accounts -.TP -.B aliasdomains -to list all assigned alias domain names -.TP -.B aliases -to list all available alias e\-mail addresses -.TP -.B catchall -to list all catch\-all destinations -.TP -.B relocated -to list the e\-mail addresses of all relocated users -.TP -.B full -to list all information mentioned above -.RE -.PP -Example: -.PP -.nf -.B vmm domaininfo sales.example.com -Domain information ------------------- - Domain Name......: sales.example.com - GID..............: 70708 - Domain Directory.: /srv/mail/c/70708 - Quota Limit/User.: Storage: 500.00 MiB; Messages: 10,000 - Active Services..: IMAP SIEVE - Transport........: lmtp:unix:private/dovecot-lmtp - Alias Domains....: 0 - Accounts.........: 1 - Aliases..........: 0 - Relocated........: 0 - Catch-All Dests..: 1 -.fi -.\" ------------------------------------ -.SS domainquota (dq) -.B vmm domainquota -.IR "fqdn storage" " [" messages ] -.RB [ force ] -.PP -This subcommand is used to configure a new quota limit for the accounts of -the domain - not for the domain itself. -.PP -The default quota limit for accounts is defined in the -.IR vmm.cfg " (" domain.quota_bytes " and " domain.quota_messages ). -.PP -The new quota limit will affect only those accounts for which the limit -has not been overridden. If you want to restore the default to all accounts, -you may pass the keyword -.BR force . -.br -When the argument -.I messages -was omitted the default number of messages -.B 0 -(zero) will be applied. -.PP -Example: -.PP -.nf -.B vmm domainquota example.com 1g force -.fi -.\" ------------------------------------ -.SS domainservices (ds) -.B vmm domainservices -.IR fqdn " [" "service ..." ] -.RB [ force ] -.PP -To define which services could be used by the users of the domain \(em with -the given -.I fqdn -\(em use this subcommand. -.PP -Each specified -.I service -will be enabled/usable. -All other services will be deactivated/unusable. -Possible service names are: -.BR imap ", " pop3 ", " sieve " and " smtp . -.br -The new service set will affect only those accounts for which the set has not -been overridden. If you want to restore the default to all accounts, you may -pass the keyword -.BR force . -.\" ------------------------------------ -.SS domaintransport (dt) -.BI "vmm domaintransport" " fqdn transport" -.RB [ force ] -.PP -A new transport for the indicated domain can be set with this subcommand. -.PP -The new transport will affect only those accounts for which the transport has -not been overridden. If you want to restore the default to all accounts, you -may pass the keyword -.BR force . -.PP -Example: -.PP -.nf -.B vmm domaintransport support.example.com dovecot: -.fi -.\" ------------------------------------ -.SS domainnote (do) -.BI "vmm domainnote" " fqdn" -.RI [ note ] -.PP -With this subcommand, it is possible to attach a note to the specified -domain. Without an argument, an existing note is removed. -.PP -Example: -.PP -.nf -.B vmm do example.com Belongs to Robert -.fi -.\" ----------------------------------------------------------------------- -.SH ALIAS DOMAIN SUBCOMMANDS -An alias domain is an alias for a domain that was previously added with the -subcommand -.BR domainadd . -All accounts, aliases and relocated users from the domain will be also -available in the alias domain. -.br -In the following is to be assumed that example.net is an alias for -example.com. -.PP -Postfix will not accept erroneously e\-mails for unknown.user@example.net -and bounce them back later to the mostly faked sender. -Postfix will immediately reject all e\-mails addressed to nonexistent -users. -.br -This behavior is ensured as long as you use the recommended database -queries in your -.I $config_directory/pgsql\-*.cf -configuration files. -.\" ------------------------------------ -.SS aliasdomainadd (ada) -.BI "vmm aliasdomainadd" " fqdn destination" -.PP -This subcommand adds the new alias domain -.RI ( fqdn ) -to the -.I destination -domain that should be aliased. -.PP -Example: -.PP -.nf -.B vmm aliasdomainadd example.net example.com -.fi -.\" ------------------------------------ -.SS aliasdomaindelete (add) -.BI "vmm aliasdomaindelete" " fqdn" -.PP -Use this subcommand if the alias domain -.I fqdn -should be removed. -.PP -Example: -.PP -.nf -.B vmm aliasdomaindelete e.g.example.com -.fi -.\" ------------------------------------ -.SS aliasdomaininfo (adi) -.BI "vmm aliasdomaininfo" " fqdn" -.PP -This subcommand shows to which domain the alias domain -.I fqdn -is assigned to. -.PP -Example: -.PP -.nf -.B vmm adi example.net -Alias domain information ------------------------- - The alias domain example.net belongs to: - * example.com -.fi -.\" ------------------------------------ -.SS aliasdomainswitch (ads) -.BI "vmm aliasdomainswitch" " fqdn destination" -.PP -If the destination of the existing alias domain -.I fqdn -should be switched to another -.I destination -use this subcommand. -.nf -.PP -Example: -.PP -.B vmm aliasdomainswitch example.name example.org -.fi -.\" ----------------------------------------------------------------------- -.SH ACCOUNT SUBCOMMANDS -.SS useradd (ua) -.B vmm useradd -.IR address " [" password ] -.PP -Use this subcommand to create a new e\-mail account for the given -.IR address . -.PP -If the -.I password -is not provided, -.B vmm -will prompt for it interactively. -When no -.I password -is provided and -.I account.random_password -is set to -.BR true ", " vmm -will generate a random password and print it to stdout after the account -has been created. -.PP -Examples: -.PP -.nf -.B vmm ua d.user@example.com \(dqA 5ecR3t P4s5\(rs/\(rs/0rd\(dq -.B vmm useradd e.user@example.com -Enter new password: -Retype new password: -.fi -.\" ------------------------------------ -.SS userdelete (ud) -.BI "vmm userdelete" " address" -.RB [ force ] -.PP -Use this subcommand to delete the account with the given -.IR address . -.PP -If there are one or more aliases with an identical destination address, -.B vmm -will abort the requested operation and show an error message. -To prevent this, specify the optional keyword -.BR force . -.\" ------------------------------------ -.SS userinfo (ui) -.B "vmm userinfo" -.IR address " [" details ] -.PP -This subcommand displays some information about the account specified by -.IR address . -.PP -If the optional argument -.I details -is given some more information will be displayed. -Possible values for -.I details -are: -.RS -.TP 8 -.B aliases -to list all alias addresses with the destination -.I address -.TP -.B du -to display the disk usage of the user's mail directory. -In order to summarize the disk usage each time this subcommand is -executed automatically, set -.I account.disk_usage -in your -.I vmm.cfg -to -.BR true . -.TP -.B full -to list all information mentioned above -.RE -.PP -Example: -.PP -.nf -.B vmm ui d.user@example.com -Account information -------------------- - Address..........: d.user@example.com - Name.............: None - UID..............: 79881 - GID..............: 70704 - Home.............: /srv/mail/2/70704/79881 - Mail_Location....: mdbox:~/mdbox - Quota Storage....: [ 0.00%] 0/500.00 MiB - Quota Messages...: [ 0.00%] 0/10,000 - Transport........: lmtp:unix:private/dovecot-lmtp - SMTP.............: disabled - POP3.............: disabled - IMAP.............: enabled - SIEVE............: enabled -.fi -.\" ------------------------------------ -.SS username (un) -.BI "vmm username" " address" -.RI [ name ] -.PP -The user's real -.I name -can be set/updated with this subcommand. -.PP -If no -.I name -is given, the value stored for the account is erased. -.PP -Example: -.PP -.nf -.B vmm un d.user@example.com \(dqJohn Doe\(dq -.fi -.\" ------------------------------------ -.SS userpassword (up) -.BI "vmm userpassword" " address" -.RI [ password ] -.PP -The password of an account can be updated with this subcommand. -.PP -If no -.I password -was provided, -.B vmm -will prompt for it interactively. -.PP -Example: -.PP -.nf -.B vmm up d.user@example.com \(dqA |\(rs/|0r3 5ecur3 P4s5\(rs/\(rs/0rd?\(dq -.fi -.\" ------------------------------------ -.SS usernote (uo) -.BI "vmm usernote" " address" -.RI [ note ] -.PP -With this subcommand, it is possible to attach a note to the specified -account. Without an argument, an existing note is removed. -.PP -Example: -.PP -.nf -.B vmm uo d.user@example.com Only needed until end of May 2012 -.fi -.\" ------------------------------------ -.SS userquota (uq) -.BI "vmm userquota" " address storage" -.RI [ messages ] -.PP -This subcommand is used to set a new quota limit for the given account. -.PP -When the argument -.I messages -was omitted the default number of messages -.B 0 -(zero) will be applied. -.PP -Instead of -.I storage -pass the keyword -.B domain -to remove the account\-specific override, causing the domain's value to be -in effect. -.PP -Example: -.PP -.nf -.B vmm userquota d.user@example.com 750m -.fi -.\" ------------------------------------ -.SS userservices (us) -.B vmm userservices -.IR address " [" "service ..." ] -.PP -To grant a user access to the specified services, use this command. -.PP -All omitted services will be deactivated/unusable for the user with the -given -.IR address . -.PP -Instead of -.I service -pass 'domain' to remove the account\-specific override, causing the -domain's value to be in effect. -.PP -Example: -.PP -.nf -.B vmm userservices d.user@example.com SMTP IMAP -.\" ------------------------------------ -.SS usertransport (ut) -.BI "vmm usertransport" " address transport" -.PP -A different -.I transport -for an account can be specified with this subcommand. -.PP -Instead of -.I transport -pass 'domain' to remove the account\-specific override, causing the -domain's value to be in effect. -.PP -Example: -.br -Assumed you want to use Dovecot's -.BR dsync (1) -to convert a user's mailbox from Maildir format to mdbox format, you -can tell Postfix to retry later. -.PP -.nf -.B vmm ut d.user@example.com \(dqretry:4.0.0 Mailbox being migrated\(dq -# convert the mailbox ... then set the transport to Dovecot's lmtp -.B vmm ut d.user@example.com lmtp:unix:private/dovecot\-lmtp -.fi -.\" ----------------------------------------------------------------------- -.SH ALIAS SUBCOMMANDS -.SS aliasadd (aa) -.BI "vmm aliasadd" " address destination ..." -.PP -This subcommand is used to create a new alias -.I address -with one or more -.I destination -addresses. -.PP -Within the destination address, the placeholders -.IR %n , -.IR %d , -and -.IR %= -will be replaced by the local part, the domain, or the email address with '@' -replaced by '=' respectively. In combination with alias domains, this enables -domain\-specific destinations. -.PP -Examples: -.PP -.nf -.B vmm aliasadd john.doe@example.com d.user@example.com -.B vmm aa support@example.com d.user@example.com e.user@example.com -.B vmm aa postmaster@example.com postmaster+%d@example.org -.fi -.\" ------------------------------------ -.SS aliasdelete (ad) -.BI "vmm aliasdelete" " address" -.RI [ destination " ...]" -.PP -This subcommand is used to delete one or multiple -.IR destination s -from the alias with the given -.IR address . -.PP -When no -.I destination -address was specified the alias with all its destinations will be deleted. -.PP -Example: -.PP -.nf -.B vmm ad support@example.com d.user@example.com -.fi -.\" ------------------------------------ -.SS aliasinfo (ai) -.BI "vmm aliasinfo" " address" -.PP -Information about the alias with the given -.I address -can be displayed with this subcommand. -.PP -Example: -.PP -.nf -.B vmm aliasinfo support@example.com -Alias information ------------------ - Mail for support@example.com will be redirected to: - * e.user@example.com -.fi -.\" ----------------------------------------------------------------------- -.SH RELOCATED SUBCOMMANDS -.SS relocatedadd (ra) -.BI "vmm relocatedadd" " address newaddress" -.PP -A new relocated user can be created with this subcommand. -.PP -.I address -is the user's ex\-email address, for example b.user@example.com, and -.I newaddress -points to the new email address where the user can be reached. -.PP -Example: -.PP -.nf -.B vmm relocatedadd b.user@example.com b\-user@company.tld -.fi -.\" ------------------------------------ -.SS relocatedinfo (ri) -.BI "vmm relocatedinfo " address -.PP -This subcommand shows the new address of the relocated user with the given -.IR address . -.PP -Example: -.PP -.nf -.B vmm relocatedinfo b.user@example.com -Relocated information ---------------------- - User `b.user@example.com' has moved to `b\-user@company.tld' -.fi -.\" ------------------------------------ -.SS relocateddelete (rd) -.BI "vmm relocateddelete " address -.PP -Use this subcommand in order to delete the relocated user with the given -.IR address . -.PP -Example: -.PP -.nf -.B vmm relocateddelete b.user@example.com -.fi -.\" ----------------------------------------------------------------------- -.SH CATCH\-ALL SUBCOMMANDS -.SS catchalladd (caa) -.BI "vmm catchalladd" " fqdn destination ..." -.PP -This subcommand allows to specify destination addresses for a domain, which -shall receive mail addressed to unknown local parts within that domain. -Those catch\-all aliases hence \(dqcatch all\(dq mail to any address in the -domain (unless a more specific alias, mailbox or relocated entry exists). -.PP -WARNING: Catch\-all addresses can cause mail server flooding because -spammers like to deliver mail to all possible combinations of names, e.g. -to all addresses between abba@example.org and zztop@example.org. -.PP -Example: -.PP -.nf -.B vmm catchalladd example.com user@example.org -.fi -.\" ------------------------------------ -.SS catchallinfo (cai) -.BI "vmm catchallinfo " fqdn -.PP -This subcommand displays information about catch\-all aliases defined for -a domain. -.PP -Example: -.PP -.nf -.B vmm catchallinfo example.com -Catch-all information ---------------------- - Mail to unknown localparts in domain example.com will be sent to: - * user@example.org -.fi -.\" ------------------------------------ -.SS catchalldelete (cad) -.BI "vmm catchalldelete " fqdn -.RI [ destination " ...]" -.PP -With this subcommand, catch\-all aliases defined for a domain can be -removed, either all of them, or those -.IR destination s -which were specified explicitly. -.PP -Example: -.PP -.nf -.B vmm catchalldelete example.com user@example.com -.fi -.\" ----------------------------------------------------------------------- -.SH FILES -.TP -.I /root/vmm.cfg -will be used when found. -.TP -.I /usr/local/etc/vmm.cfg -will be used when the above file doesn't exist. -.TP -.I /etc/vmm.cfg -will be used when none of the both above mentioned files exists. -.\" ----------------------------------------------------------------------- -.SH SEE ALSO -.BR dsync (1), -.BR transport (5), -.BR vmm.cfg (5) -.\" ----------------------------------------------------------------------- -.SH INTERNET RESOURCES -.TP -Homepage -http://vmm.localdomain.org/ -.TP -Project site -http://sf.net/projects/vmm/ -.TP -Bug tracker -https://bitbucket.org/pvo/vmm/issues -.\" ----------------------------------------------------------------------- -.SH COPYING -vmm and its manual pages were written by Pascal Volk <user+vmm AT -localhost.localdomain.org> and are licensed under the terms of the BSD -License. \ No newline at end of file diff -r 659c4476c57c -r b678a1c43027 man/man5/vmm.cfg.5 --- a/man/man5/vmm.cfg.5 Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,599 +0,0 @@ -.TH "VMM.CFG" "5" "2014-02-17" "vmm 0.6" "vmm" -.SH NAME -vmm.cfg \- configuration file for vmm -.\" ----------------------------------------------------------------------- -.SH SYNOPSIS -vmm.cfg -.\" ----------------------------------------------------------------------- -.SH DESCRIPTION -.BR vmm (1) -reads its configuration data from -.IR vmm.cfg . -.PP -The configuration file is split into multiple sections. -A section starts with the section name, enclosed in square brackets -.RB ` [ "' and `" ] ', -followed by -.RI ` option " = " value ' -pairs. -.br -Whitespace around the `=' and at the end of a value is ignored. -Empty lines and lines starting with `#' or `;' will be ignored. -.PP -Each value uses one of the following data types: -.TP 8 -.I Boolean -to indicate if something is enabled/activated (true) or -disabled/deactivated (false). -.br -Accepted values for -.I true -are: -.BR 1 , " yes" , " true" " and " on . -.br -Accepted values for -.I false -are: -.BR 0 , " no" , " false" " and " off . -.TP -.I Int -an integer number, written without a fractional or decimal component. -.br -For example -.BR 1 , " 50" " or " 321 -are integers. -.TP -.I String -a sequence of characters and/or numbers. -.br -For example -.RB ` word "', `" "hello world" "' or `" /usr/bin/strings ' -are strings. -.PP -Most options have a default value, shown in parentheses after the option's -name. -In order to use a option's default setting, comment out the line, either -with a -.BR # " or " ; -or simply remove the setting from -.IR vmm.cfg . -.PP -A minimal -.I vmm.cfg -would be: -.PP -.nf -[database] -user = me -pass = xxxxxxxx - -[misc] -dovecot_version = 1.2.16 -.fi -.\" ----------------------------------------------------------------------- -.SH SEARCH ORDER -By default -.BR vmm (1) -looks for the -.I vmm.cfg -file in the following directories in the order listed: -.RS -.PD 0 -.TP -.I -/root -.TP -.I -/usr/local/etc -.TP -.I -/etc -.PD -.RE -.PP -The first configuration file found will be used. -.\" ----------------------------------------------------------------------- -.SH SECTION ACCOUNT -The options in the section -.B account -are used to specify user account related settings. -.SS account.delete_directory -.BR delete_directory " (default: false) :" -.I Boolean -.PP -Determines the behavior of -.BR vmm (1) -when an account is deleted (userdelete). -If this option is set to -.I true -the user's home directory will be deleted recursively. -.\" ------------------------------------ -.SS account.directory_mode -.BR directory_mode " (default: 448) :" -.I Int -.PP -Access mode for a user's home directory and all directories inside. -The value has to be specified in decimal (base 10) notation. -.br -For example: `drwx\-\-\-\-\-\-' \(-> octal 0700 \(-> decimal 448 -.\" ------------------------------------ -.SS account.disk_usage -.BR disk_usage " (default: false) :" -.I Boolean -.PP -Determines whether the disk usage of a user's mail directory always should -be summarized, using -.BR du (1), -and displayed with the account information (userinfo). -.PP -This could be slow on large Maildirs. -When you have enabled quotas, -.BR vmm 's -userinfo subcommand will also display the current quota usage of the -account. -You may also use userinfo's optional details\-argument -.BR du " or " full , -in order to display the current disk usage of an account's mail directory. -.\" ------------------------------------ -.SS account.password_length -.BR password_length " (default: 8) :" -.I Int -.PP -Determines how many characters and/or numbers should be used for randomly -generated passwords. -Any value less than 8 will be increased to 8. -.\" ------------------------------------ -.SS account.random_password -.BR random_password " (default: false) :" -.I Boolean -.PP -Determines whether -.BR vmm (1) -should generate a random password when no password was given for the -useradd subcommand. -If this option is set to -.I false -.B vmm -will prompt you to enter a password for the new account. -.PP -You can specify the password length of generated passwords with the -.I account.password_length -option. -.\" ----------------------------------------------------------------------- -.SH SECTION BIN -The -.B bin -section is used to specify some paths to some binaries required by -.BR vmm (1). -.SS bin.dovecotpw -.BR dovecotpw " (default: /usr/sbin/dovecotpw) :" -.I String -.PP -The absolute path to the -.BR dovecotpw (1) -binary. -Use the absolute path to the -.BR doveadm (1) -binary, if you are using Dovecot v2.0. -.PP -This binary is used to generate a password hash, if -.I misc.password_scheme -is set to one of `CRAM\-MD5', `HMAC\-MD5', `LANMAN', `OTP', `RPA' or -`SKEY'. -This binary will be also required if your Python installation doesn't -support the: -.IP \(bu 4 -md4 hash algorithm (hashlib + OpenSSL or PyCrypto) used for the password -schemes: `PLAIN\-MD4' and `NTLM' -.IP \(bu -sha256 hash algorithm (hashlib or PyCrypto \(>= 2.1.0alpha1) used for the -password schemes: `SHA256' and `SSHA256' -.IP \(bu -sha512 hash algorithm (hashlib) used for the password schemes: `SHA512' and -`SSHA512' -.PP -The -.BR doveadm (1) -binary is also used to create a user's INBOX and additional mailboxes -.RI ( mailbox.folders ), -when the -.I mailbox.format -is set to -.BR mdbox " or " sdbox . -.\" ------------------------------------ -.SS bin.du -.BR du " (default: /usr/bin/du) :" -.I String -.PP -The absolute path to -.BR du (1). -This binary is used to summarize the disk usage of a user's mail directory. -.\" ------------------------------------ -.SS bin.postconf -.BR postconf " (default: /usr/sbin/postconf) :" -.I String -.PP -The absolute path to Postfix' -.BR postconf (1). -This binary is required when -.BR vmm (1) -has to check for some Postfix settings, e.g. the -.IR virtual_alias_expansion_limit . -.\" ----------------------------------------------------------------------- -.SH SECTION DATABASE -The -.B database -section is used to specify some options required to connect to the -database. -.SS database.host -.BR host " (default: localhost) :" -.I String -.PP -Hostname or IP address of the database server. -.\" ------------------------------------ -.SS database.module -.BR module " (default: psycopg2) :" -.I String -.PP -The Python PostgreSQL database adapter module to be used. -Supported modules are -.BR psycopg2 " and " pyPgSQL . -.\" ------------------------------------ -.SS database.name -.BR name " (default: mailsys) :" -.I String -.PP -Name of the database. -.\" ------------------------------------ -.SS database.pass -.BR pass " (default: " None ") :" -.I String -.PP -Database password. -.\" ------------------------------------ -.SS database.port -.BR port " (default: 5432) :" -.I Int -.PP -The TCP port, on which the database server is listening for connections. -.\" ------------------------------------ -.SS database.sslmode -.BR sslmode " (default: prefer) :" -.I String -.PP -Determines whether and with what priority an SSL connection will be -negotiated with the database server. -Possible values are: -.BR disabled ", " allow ", " prefer ", " require ", " verify\-ca " and " -.BR verify\-full . -The modes -.BR verify\-ca " and " verify\-full -are available since PostgreSQL 8.4 -.PP -This setting will be ignored when the -.I database.module -is set to -.BR pyPgSQL . -.\" ------------------------------------ -.SS database.user -.BR user " (default: " None ") :" -.I String -.PP -Name of the database user. -.\" ----------------------------------------------------------------------- -.SH SECTION DOMAIN -The -.B domain -section specifies some domain related settings. -.PP -The quota limit (quota_bytes and quota_messages), service settings (imap, -pop3, sieve and smtp) and the transport setting will be applied when a -domain is created. -In order to modify those settings for an existing domain, use one of -the following -.BR vmm (1) -subcommands: -.PP -.TP -.B domainquota -in order to update a domain's quota limit -.TP -.B domainservices -in order to assign a different service set to a domain -.TP -.B domaintransport -in order to set a new default domain transport -.PP -When an account is created, it inherits all the settings of the domain -to which it is added. -Different settings for an existing account can be set using the subcommands -.BR userquota ", " userservices " and " usertransport . -.\" ------------------------------------ -.SS domain.auto_postmaster -.BR auto_postmaster " (default: true) :" -.I Boolean -.PP -Determines if -.BR vmm (1) -should create also a postmaster account when a new domain is created -(domainadd). -.\" ------------------------------------ -.SS domain.delete_directory -.BR delete_directory " (default: false) :" -.I Boolean -.PP -Specifies whether the domain directory and all user directories inside -should be deleted when a domain is deleted (domaindelete). -.\" ------------------------------------ -.SS domain.directory_mode -.BR directory_mode " (default: 504) :" -.I Int -.PP -Access mode for the domain directory in decimal (base 10) notation. -.br -For example: `drwxrwx\-\-\-' \(-> octal 0770 \(-> decimal 504 -.\" ------------------------------------ -.SS domain.force_deletion -.BR force_deletion " (default: false) :" -.I Boolean -.PP -Force the deletion of accounts and aliases when a domain is deleted -(domaindelete). -.\" ------------------------------------ -.SS domain.imap -.BR imap " (default: true) :" -.I Boolean -.PP -Determines whether newly created users can log in via IMAP. -.\" ------------------------------------ -.SS domain.pop3 -.BR pop3 " (default: true) :" -.I Boolean -.PP -Determines whether newly created users can log in via POP3. -.\" ------------------------------------ -.SS domain.quota_bytes -.BR quota_bytes " (default: 0) :" -.I String -.PP -Quota limit in bytes. -0 means unlimited. -This limit will be applied to all newly created domains. -.PP -The option's value can be written as an integer value, e.g.: -.BR 20480 . -It's also possible to append one of the following prefixes to the limit: -.BR b " (bytes), " k " (kilobytes), " M " (megabytes) or " G -(gigabytes). -.br -1024 is the same as 1024b or 1k. -.\" ------------------------------------ -.SS domain.quota_messages -.BR quota_messages " (default: 0) :" -.I Int -.PP -Quota limit in number of messages. -0 means unlimited. -This limit will be applied to all newly created domains. -.\" ------------------------------------ -.SS domain.sieve -.BR sieve " (default: true) :" -.I Boolean -.PP -Determines whether newly created users can log in via SIEVE (ManageSieve). -.\" ------------------------------------ -.SS domain.smtp -.BR smtp " (default: true) :" -.I Boolean -.PP -Determines whether newly created users can log in via SMTP (SMTP AUTH). -.\" ------------------------------------ -.SS domain.transport -.BR transport " (default: dovecot:) :" -.I String -.PP -Default transport for domains and accounts. -For details see -.BR transport (5). -.\" ----------------------------------------------------------------------- -.SH SECTION MAILBOX -The -.B mailbox -section is used to specify some options for new created mailboxes in the -users home directories. -The INBOX will be created always. -.SS mailbox.folders -.BR folders " (default: Drafts:Sent:Templates:Trash) :" -.I String -.PP -A colon separated list of mailboxes that should be created. -If no additionally mailboxes should be created, set the value of this -option to a single colon -.RB (` : '). -.PP -If you want to create folders containing one or more subfolders, separate -them with a single dot -.RB (` . '). -.PP -If you want to use internationalized mailbox names (e.g. `Wysłane' or -`Gelöschte Objekte'), write their names UTF\-8 encoded. -.BR vmm (1) -will convert internationalized mailbox names to a modified version of the -UTF\-7 encoding (see also: RFC 3501, section 5.1.3). -.\" ------------------------------------ -.SS mailbox.format -.BR format " (default: maildir) :" -.I String -.PP -The mailbox format to be used for a user's mailbox. -Depending on the used Dovecot version -.RI ( misc.dovecot_version ) -.BR vmm (1) -supports up to three formats: -.TP 8 -.B maildir -Dovecot \(>= v1.0.0 -.TP -.B mdbox -Dovecot \(>= v2.0.beta5 -.TP -.B sdbox -Dovecot \(>= v2.0.rc3 -.\" ------------------------------------ -.SS mailbox.root -.BR root " (default: Maildir) :" -.I String -.PP -Name of the mailbox root directory in a user's home directory. -Commonly used names, depending on the used -.IR mailbox.format , -are -.BR Maildir ", " mdbox " or " sdbox . -.\" ------------------------------------ -.SS mailbox.subscribe -.BR subscribe " (default: true) :" -.I Boolean -.PP -When this option is set to -.BR true , -the mailboxes from the -.I mailbox.folders -option will be listed in the user's subscriptions file. -If you don't want to subscribe the created mailboxes, set this option to -.BR false . -.\" ----------------------------------------------------------------------- -.SH SECTION MISC -The -.I misc -section is used to define miscellaneous settings. -.SS misc.base_directory -.BR base_directory " (default: /srv/mail) :" -.I String -.PP -All domain directories will be created inside this directory. -.\" ------------------------------------ -.SS misc.crypt_blowfish_rounds -.BR crypt_blowfish_rounds " (default: 5) :" -.I Int -.PP -Number of encryption rounds for the -.I password_scheme -.BR BLF\-CRYPT . -.PP -The value must be in range -.BR 4 " \- " 31 . -.\" ------------------------------------ -.SS misc.crypt_sha256_rounds -.BR crypt_sha256_rounds " (default: 5000) :" -.I Int -.PP -Number of encryption rounds for the -.I password_scheme -.BR SHA256\-CRYPT . -.PP -The value must be in range -.BR 1000 " \- " 999999999 . -.\" ------------------------------------ -.SS misc.crypt_sha512_rounds -.BR crypt_sha512_rounds " (default: 5000) :" -.I Int -.PP -Number of encryption rounds for the -.I password_scheme -.BR SHA512\-CRYPT . -.PP -The value must be in range -.BR 1000 " \- " 999999999 . -.\" ------------------------------------ -.SS misc.dovecot_version -.BR dovecot_version " (default: " None ") :" -.I String -.PP -The version number of the currently used Dovecot version. -(see: -.BR "dovecot \-\-version" ) -.br -When, for example, the command -.B dovecot \-\-version -prints -.IR "2.0.beta4 (8818db00d347)" , -set the value of this option to -.BR 2.0.beta4 . -.\" ------------------------------------ -.SS misc.password_scheme -.BR password_scheme " (default: CRAM\-MD5) :" -.I String -.PP -Password scheme to use. -To get a list of all usable password schemes execute the command -.BR "vmm lp" . -.PP -With Dovecot \(>= v1.1.alpha1 it is also possible to append an encoding -suffix to the password_scheme. -Supported encoding suffixes are: -.BR .b64 ", " .base64 " and " .hex . -For example: PLAIN.BASE64 -.IP Note: -When setting another password scheme than -.BR PLAIN " or " CRAM\-MD5 , -you have to remove -.B cram\-md5 -from the -.I auth_mechanisms -setting in your -.IR dovecot/conf.d/10\-auth.conf . -.\" ----------------------------------------------------------------------- -.SH EXAMPLE -An example configuration. -All options that are not listed in the configuration file will have their -default values. -.PP -.nf -[account] -password_length = 10 -random_password = true - -[bin] -dovecotpw = /usr/bin/doveadm - -[database] -host = dbsrv8.example.net -pass = PY_SRJ}L/0p\-oOk -port = 5433 -sslmode = require -user = vmm - -[domain] -quota_bytes = 500M -quota_messages = 10000 -transport = lmtp:unix:private/dovecot\-lmtp - -[mailbox] -folders = Drafts:Sent:Templates:Trash:Lists.Dovecot:Lists.Postfix - -[misc] -crypt_sha512_rounds = 10000 -dovecot_version = 2.0.beta4 -password_scheme = SHA512\-CRYPT.hex -.fi -.\" ----------------------------------------------------------------------- -.SH SEE ALSO -.BR postconf (1), -.BR vmm (1), -.BR transport (5) -.\" ----------------------------------------------------------------------- -.SH INTERNET RESOURCES -.TP -Homepage -http://vmm.localdomain.org/ -.TP -Project site -http://sf.net/projects/vmm/ -.TP -Bug tracker -https://bitbucket.org/pvo/vmm/issues -.\" ----------------------------------------------------------------------- -.SH COPYING -vmm and its manual pages were written by Pascal Volk <user+vmm AT -localhost.localdomain.org> and are licensed under the terms of the BSD -License. \ No newline at end of file diff -r 659c4476c57c -r b678a1c43027 pgsql/create_tables-dovecot-1.2.x.pgsql --- a/pgsql/create_tables-dovecot-1.2.x.pgsql Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,770 +0,0 @@ -SET client_encoding = 'UTF8'; -SET client_min_messages = warning; - - -CREATE SEQUENCE transport_id; - -CREATE SEQUENCE mailboxformat_id; - -CREATE SEQUENCE maillocation_id; - -CREATE SEQUENCE quotalimit_id; - -CREATE SEQUENCE service_set_id; - -CREATE SEQUENCE domain_gid - START WITH 70000 - INCREMENT BY 1 - MINVALUE 70000 - MAXVALUE 4294967294 - NO CYCLE; - -CREATE SEQUENCE users_uid - START WITH 70000 - INCREMENT BY 1 - MINVALUE 70000 - MAXVALUE 4294967294 - NO CYCLE; - - -CREATE TABLE transport ( - tid bigint NOT NULL DEFAULT nextval('transport_id'), - transport varchar(270) NOT NULL, -- smtps:[255-char.host.name:50025] - CONSTRAINT pkey_transport PRIMARY KEY (tid), - CONSTRAINT ukey_transport UNIQUE (transport) -); --- Insert default transport -INSERT INTO transport(transport) VALUES ('dovecot:'); - -CREATE TABLE mailboxformat ( - fid bigint NOT NULL DEFAULT nextval('mailboxformat_id'), - format varchar(20) NOT NULL, - CONSTRAINT pkey_mailboxformat PRIMARY KEY (fid), - CONSTRAINT ukey_mailboxformat UNIQUE (format) -); --- Insert supported mailbox formats -INSERT INTO mailboxformat(format) VALUES ('maildir'); -INSERT INTO mailboxformat(format) VALUES ('mdbox'); -INSERT INTO mailboxformat(format) VALUES ('sdbox'); - -CREATE TABLE maillocation ( - mid bigint NOT NULL DEFAULT nextval('maillocation_id'), - fid bigint NOT NULL DEFAULT 1, - directory varchar(20) NOT NULL, - extra varchar(1024), - CONSTRAINT pkey_maillocation PRIMARY KEY (mid), - CONSTRAINT fkey_maillocation_fid_mailboxformat FOREIGN KEY (fid) - REFERENCES mailboxformat (fid) -); --- Insert default Maildir-folder name -INSERT INTO maillocation(directory) VALUES ('Maildir'); - -CREATE TABLE quotalimit ( - qid bigint NOT NULL DEFAULT nextval('quotalimit_id'), - bytes bigint NOT NULL, - messages integer NOT NULL DEFAULT 0, - CONSTRAINT pkey_quotalimit PRIMARY KEY (qid), - CONSTRAINT ukey_quotalimit UNIQUE (bytes, messages) -); --- Insert default (non) quota limit -INSERT INTO quotalimit(bytes, messages) VALUES (0, 0); - -CREATE TABLE service_set ( - ssid bigint NOT NULL DEFAULT nextval('service_set_id'), - smtp boolean NOT NULL DEFAULT TRUE, - pop3 boolean NOT NULL DEFAULT TRUE, - imap boolean NOT NULL DEFAULT TRUE, - sieve boolean NOT NULL DEFAULT TRUE, - CONSTRAINT pkey_service_set PRIMARY KEY (ssid), - CONSTRAINT ukey_service_set UNIQUE (smtp, pop3, imap, sieve) -); --- Insert all possible service combinations -COPY service_set (smtp, pop3, imap, sieve) FROM stdin; -TRUE TRUE TRUE TRUE -FALSE TRUE TRUE TRUE -TRUE FALSE TRUE TRUE -FALSE FALSE TRUE TRUE -TRUE TRUE FALSE TRUE -FALSE TRUE FALSE TRUE -TRUE FALSE FALSE TRUE -FALSE FALSE FALSE TRUE -TRUE TRUE TRUE FALSE -FALSE TRUE TRUE FALSE -TRUE FALSE TRUE FALSE -FALSE FALSE TRUE FALSE -TRUE TRUE FALSE FALSE -FALSE TRUE FALSE FALSE -TRUE FALSE FALSE FALSE -FALSE FALSE FALSE FALSE -\. - -CREATE TABLE domain_data ( - gid bigint NOT NULL DEFAULT nextval('domain_gid'), - qid bigint NOT NULL DEFAULT 1, -- default quota limit - ssid bigint NOT NULL DEFAULT 1, -- default service set - tid bigint NOT NULL DEFAULT 1, -- default transport - domaindir varchar(40) NOT NULL, --/srv/mail/$RAND/4294967294 - note text NULL DEFAULT NULL, - CONSTRAINT pkey_domain_data PRIMARY KEY (gid), - CONSTRAINT fkey_domain_data_qid_quotalimit FOREIGN KEY (qid) - REFERENCES quotalimit (qid), - CONSTRAINT fkey_domain_data_ssid_service_set FOREIGN KEY (ssid) - REFERENCES service_set (ssid), - CONSTRAINT fkey_domain_data_tid_transport FOREIGN KEY (tid) - REFERENCES transport (tid) -); - -CREATE TABLE domain_name ( - domainname varchar(255) NOT NULL, - gid bigint NOT NULL, - is_primary boolean NOT NULL, - CONSTRAINT pkey_domain_name PRIMARY KEY (domainname), - CONSTRAINT fkey_domain_name_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - -CREATE TABLE users ( - local_part varchar(64) NOT NULL,-- only localpart w/o '@' - passwd varchar(270) NOT NULL, - name varchar(128) NULL, - uid bigint NOT NULL DEFAULT nextval('users_uid'), - gid bigint NOT NULL, - mid bigint NOT NULL DEFAULT 1, - qid bigint NULL DEFAULT NULL, - ssid bigint NULL DEFAULT NULL, - tid bigint NULL DEFAULT NULL, - note text NULL DEFAULT NULL, - CONSTRAINT pkey_users PRIMARY KEY (local_part, gid), - CONSTRAINT ukey_users_uid UNIQUE (uid), - CONSTRAINT fkey_users_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid), - CONSTRAINT fkey_users_mid_maillocation FOREIGN KEY (mid) - REFERENCES maillocation (mid), - CONSTRAINT fkey_users_qid_quotalimit FOREIGN KEY (qid) - REFERENCES quotalimit (qid), - CONSTRAINT fkey_users_ssid_service_set FOREIGN KEY (ssid) - REFERENCES service_set (ssid), - CONSTRAINT fkey_users_tid_transport FOREIGN KEY (tid) - REFERENCES transport (tid) -); - -CREATE TABLE userquota ( - uid bigint NOT NULL, - bytes bigint NOT NULL DEFAULT 0, - messages integer NOT NULL DEFAULT 0, - CONSTRAINT pkey_userquota PRIMARY KEY (uid), - CONSTRAINT fkey_userquota_uid_users FOREIGN KEY (uid) - REFERENCES users (uid) ON DELETE CASCADE -); - -CREATE TABLE alias ( - gid bigint NOT NULL, - address varchar(64) NOT NULL,-- only localpart w/o '@' - destination varchar(320) NOT NULL, - CONSTRAINT pkey_alias PRIMARY KEY (gid, address, destination), - CONSTRAINT fkey_alias_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - -CREATE TABLE relocated ( - gid bigint NOT NULL, - address varchar(64) NOT NULL, - destination varchar(320) NOT NULL, - CONSTRAINT pkey_relocated PRIMARY KEY (gid, address), - CONSTRAINT fkey_relocated_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - -CREATE TABLE catchall ( - gid bigint NOT NULL, - destination varchar(320) NOT NULL, - CONSTRAINT pkey_catchall PRIMARY KEY (gid, destination), - CONSTRAINT fkey_catchall_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - -CREATE OR REPLACE VIEW postfix_gid AS - SELECT gid, domainname - FROM domain_name; - -CREATE OR REPLACE VIEW vmm_domain_info AS - SELECT gid, count(uid) AS accounts, - (SELECT count(DISTINCT address) - FROM alias - WHERE alias.gid = domain_data.gid) AS aliases, - (SELECT count(gid) - FROM relocated - WHERE relocated.gid = domain_data.gid) AS relocated, - (SELECT count(gid) - FROM domain_name - WHERE domain_name.gid = domain_data.gid - AND NOT domain_name.is_primary) AS aliasdomains, - (SELECT count(gid) - FROM catchall - WHERE catchall.gid = domain_data.gid) AS catchall - FROM domain_data - LEFT JOIN domain_name USING (gid) - LEFT JOIN users USING (gid) - WHERE domain_name.is_primary - GROUP BY gid; - --- ########################################################################## -- - -CREATE LANGUAGE plpgsql; - --- ######################## TYPEs ########################################### -- - --- --- --- Data type for function postfix_virtual_mailbox(varchar, varchar) --- --- -CREATE TYPE address_maildir AS ( - address varchar(320), - maildir text -); --- --- --- Data type for function dovecotpassword(varchar, varchar) --- --- -CREATE TYPE dovecotpassword AS ( - userid varchar(320), - password varchar(270), - smtp boolean, - pop3 boolean, - imap boolean, - sieve boolean -); --- --- --- Data type for function dovecotquotauser(varchar, varchar) --- --- -CREATE TYPE dovecotquotauser AS ( - userid varchar(320), - uid bigint, - gid bigint, - home text, - mail text, - quota_rule text -); --- --- --- Data type for function dovecotuser(varchar, varchar) --- --- -CREATE TYPE dovecotuser AS ( - userid varchar(320), - uid bigint, - gid bigint, - home text, - mail text -); --- --- --- Data type for functions: postfix_relocated_map(varchar, varchar) --- postfix_virtual_alias_map(varchar, varchar) --- --- -CREATE TYPE recipient_destination AS ( - recipient varchar(320), - destination text -); --- --- --- Data type for function postfix_transport_map(varchar, varchar) --- --- -CREATE TYPE recipient_transport AS ( - recipient varchar(320), - transport text -); --- --- --- Data type for function postfix_virtual_uid_map(varchar, varchar) --- --- -CREATE TYPE recipient_uid AS ( - recipient varchar(320), - uid bigint -); --- --- --- Data type for function postfix_smtpd_sender_login_map(varchar, varchar) --- --- -CREATE TYPE sender_login AS ( - sender varchar(320), - login text -); - --- ######################## TRIGGERs ######################################## -- - -CREATE OR REPLACE FUNCTION domain_primary_trigger() RETURNS TRIGGER AS $$ -DECLARE - primary_count bigint; -BEGIN - SELECT INTO primary_count count(gid) + NEW.is_primary::integer - FROM domain_name - WHERE domain_name.gid = NEW.gid - AND is_primary; - - IF (primary_count > 1) THEN - RAISE EXCEPTION 'There can only be one domain marked as primary.'; - END IF; - - RETURN NEW; -END; -$$ LANGUAGE plpgsql STABLE; - - -CREATE TRIGGER primary_count_ins BEFORE INSERT ON domain_name - FOR EACH ROW EXECUTE PROCEDURE domain_primary_trigger(); - -CREATE TRIGGER primary_count_upd AFTER UPDATE ON domain_name - FOR EACH ROW EXECUTE PROCEDURE domain_primary_trigger(); - - -CREATE OR REPLACE FUNCTION merge_userquota() RETURNS TRIGGER AS $$ -BEGIN - IF NEW.messages < 0 OR NEW.messages IS NULL THEN - IF NEW.messages IS NULL THEN - NEW.messages = 0; - ELSE - NEW.messages = -NEW.messages; - END IF; - RETURN NEW; - END IF; - LOOP - UPDATE userquota - SET bytes = bytes + NEW.bytes, messages = messages + NEW.messages - WHERE uid = NEW.uid; - IF found THEN - RETURN NULL; - END IF; - BEGIN - IF NEW.messages = 0 THEN - INSERT INTO userquota VALUES (NEW.uid, NEW.bytes, NULL); - ELSE - INSERT INTO userquota VALUES (NEW.uid, NEW.bytes, -NEW.messages); - END IF; - RETURN NULL; - EXCEPTION - WHEN unique_violation THEN - -- do nothing, and loop to try the UPDATE again - WHEN foreign_key_violation THEN - -- break the loop: a non matching uid means no such user - RETURN NULL; - END; - END LOOP; -END; -$$ LANGUAGE plpgsql; - - -CREATE TRIGGER mergeuserquota BEFORE INSERT ON userquota - FOR EACH ROW EXECUTE PROCEDURE merge_userquota(); - --- ######################## FUNCTIONs ####################################### -- - --- --- --- Parameters (from login name [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: dovecotpassword records --- --- Required access privileges for your dovecot database user: --- GRANT SELECT ON users, domain_name, service_set TO dovecot; --- --- For more details see http://wiki.dovecot.org/AuthDatabase/SQL --- --- -CREATE OR REPLACE FUNCTION dovecotpassword( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotpassword -AS $$ - DECLARE - record dovecotpassword; - userid varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT userid, passwd, smtp, pop3, imap, sieve - FROM users, service_set, domain_data - WHERE users.gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - AND users.gid = domain_data.gid - AND CASE WHEN - users.ssid IS NOT NULL - THEN - service_set.ssid = users.ssid - ELSE - service_set.ssid = domain_data.ssid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Nearly the same as function dovecotuser below. It returns additionally the --- field quota_rule. --- --- Required access privileges for your dovecot database user: --- GRANT SELECT --- ON users, domain_data, domain_name, maillocation, mailboxformat, --- quotalimit --- TO dovecot; --- --- -CREATE OR REPLACE FUNCTION dovecotquotauser( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotquotauser -AS $$ - DECLARE - record dovecotquotauser; - userid varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT userid, uid, did, domaindir || '/' || uid AS home, - format || ':~/' || directory AS mail, '*:bytes=' || - bytes || ':messages=' || messages AS quota_rule - FROM users, domain_data, mailboxformat, maillocation, quotalimit - WHERE users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - AND mailboxformat.fid = maillocation.fid - AND domain_data.gid = did - AND CASE WHEN - users.qid IS NOT NULL - THEN - quotalimit.qid = users.qid - ELSE - quotalimit.qid = domain_data.qid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from login name [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: dovecotuser records --- --- Required access privileges for your dovecot database user: --- GRANT SELECT --- ON users, domain_data, domain_name, maillocation, mailboxformat --- TO dovecot; --- --- For more details see http://wiki.dovecot.org/UserDatabase --- --- -CREATE OR REPLACE FUNCTION dovecotuser( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotuser -AS $$ - DECLARE - record dovecotuser; - userid varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT userid, uid, did, domaindir || '/' || uid AS home, - format || ':~/' || directory AS mail - FROM users, domain_data, mailboxformat, maillocation - WHERE users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - AND mailboxformat.fid = maillocation.fid - AND domain_data.gid = did - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_destination records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON domain_name, relocated TO postfix; --- --- For more details see postconf(5) section relocated_maps and relocated(5) --- --- -CREATE OR REPLACE FUNCTION postfix_relocated_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_destination -AS $$ - DECLARE - record recipient_destination; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT recipient, destination - FROM relocated - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from _sender_ address (MAIL FROM) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: SASL _login_ names that own _sender_ addresses (MAIL FROM): --- set of sender_login records. --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON domain_name, users, alias TO postfix; --- --- For more details see postconf(5) section smtpd_sender_login_maps --- --- -CREATE OR REPLACE FUNCTION postfix_smtpd_sender_login_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF sender_login -AS $$ - DECLARE - rec sender_login; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - sender varchar(320) := localpart || '@' || the_domain; - BEGIN - -- Get all addresses for 'localpart' in the primary and aliased domains - FOR rec IN - SELECT sender, local_part || '@' || domainname - FROM domain_name, users - WHERE domain_name.gid = did - AND users.gid = did - AND users.local_part = localpart - LOOP - RETURN NEXT rec; - END LOOP; - IF NOT FOUND THEN - -- Loop over the alias addresses for localpart@the_domain - FOR rec IN - SELECT DISTINCT sender, destination - FROM alias - WHERE alias.gid = did - AND alias.address = localpart - LOOP - RETURN NEXT rec; - END LOOP; - END IF; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_transport records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON users, transport, domain_name TO postfix; --- --- For more details see postconf(5) section transport_maps and transport(5) --- --- -CREATE OR REPLACE FUNCTION postfix_transport_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_transport -AS $$ - DECLARE - record recipient_transport; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname = the_domain); - transport_id bigint; - BEGIN - IF did IS NULL THEN - RETURN; - END IF; - - SELECT tid INTO transport_id - FROM users - WHERE gid = did AND local_part = localpart; - - IF transport_id IS NULL THEN - SELECT tid INTO STRICT transport_id - FROM domain_data - WHERE gid = did; - END IF; - - FOR record IN - SELECT recipient, transport - FROM transport - WHERE tid = transport_id - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_destination records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON alias, domain_name TO postfix; --- --- For more details see postconf(5) section virtual_alias_maps and virtual(5) --- --- -CREATE OR REPLACE FUNCTION _interpolate_destination( - IN destination varchar, localpart varchar, IN the_domain varchar) - RETURNS varchar -AS $$ - DECLARE - result varchar(320); - BEGIN - IF position('%' in destination) = 0 THEN - RETURN destination; - END IF; - result := replace(destination, '%n', localpart); - result := replace(result, '%d', the_domain); - result := replace(result, '%=', localpart || '=' || the_domain); - RETURN result; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; - -CREATE OR REPLACE FUNCTION postfix_virtual_alias_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_destination -AS $$ - DECLARE - recordc recipient_destination; - record recipient_destination; - catchall_cursor refcursor; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT recipient, - _interpolate_destination(destination, localpart, the_domain) - FROM alias - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - - IF NOT FOUND THEN - -- There is no matching virtual_alias. If there are no catchall - -- records for this domain, we can just return NULL since Postfix - -- will then later consult mailboxes/relocated itself. But if - -- there is a catchall destination, then it would take precedence - -- over mailboxes/relocated, which is not what we want. Therefore, - -- we must first find out if the query is for an existing mailbox - -- or relocated entry and return the identity mapping if that is - -- the case - OPEN catchall_cursor FOR - SELECT recipient, - _interpolate_destination(destination, localpart, the_domain) - FROM catchall - WHERE gid = did; - FETCH NEXT FROM catchall_cursor INTO recordc; - - IF recordc IS NOT NULL THEN - -- Since there are catchall records for this domain - -- check the mailbox and relocated records and return identity - -- if a matching record exists. - FOR record IN - SELECT recipient, recipient as destination - FROM users - WHERE gid = did - AND local_part = localpart - UNION SELECT recipient, recipient as destination - FROM relocated - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - - IF NOT FOUND THEN - -- There were no records found for mailboxes/relocated, - -- so now we can actually iterate the cursor and populate - -- the return set - LOOP - RETURN NEXT recordc; - FETCH NEXT FROM catchall_cursor INTO recordc; - EXIT WHEN recordc IS NULL; - END LOOP; - END IF; - END IF; - CLOSE catchall_cursor; - END IF; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: address_maildir records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON domain_data,domain_name,maillocation,users TO postfix; --- --- For more details see postconf(5) section virtual_mailbox_maps --- --- -CREATE OR REPLACE FUNCTION postfix_virtual_mailbox_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF address_maildir -AS $$ - DECLARE - rec address_maildir; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - address varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR rec IN - SELECT address, domaindir||'/'||users.uid||'/'||directory||'/' - FROM domain_data, users, maillocation - WHERE domain_data.gid = did - AND users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - LOOP - RETURN NEXT rec; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_uid records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON users, domain_name TO postfix; --- --- For more details see postconf(5) section virtual_uid_maps --- --- -CREATE OR REPLACE FUNCTION postfix_virtual_uid_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF recipient_uid -AS $$ - DECLARE - record recipient_uid; - recipient varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT recipient, uid - FROM users - WHERE gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; diff -r 659c4476c57c -r b678a1c43027 pgsql/create_tables.pgsql --- a/pgsql/create_tables.pgsql Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,747 +0,0 @@ -SET client_encoding = 'UTF8'; -SET client_min_messages = warning; - - -CREATE SEQUENCE transport_id; - -CREATE SEQUENCE mailboxformat_id; - -CREATE SEQUENCE maillocation_id; - -CREATE SEQUENCE quotalimit_id; - -CREATE SEQUENCE service_set_id; - -CREATE SEQUENCE domain_gid - START WITH 70000 - INCREMENT BY 1 - MINVALUE 70000 - MAXVALUE 4294967294 - NO CYCLE; - -CREATE SEQUENCE users_uid - START WITH 70000 - INCREMENT BY 1 - MINVALUE 70000 - MAXVALUE 4294967294 - NO CYCLE; - - -CREATE TABLE transport ( - tid bigint NOT NULL DEFAULT nextval('transport_id'), - transport varchar(270) NOT NULL, -- smtps:[255-char.host.name:50025] - CONSTRAINT pkey_transport PRIMARY KEY (tid), - CONSTRAINT ukey_transport UNIQUE (transport) -); --- Insert default transport -INSERT INTO transport(transport) VALUES ('dovecot:'); - -CREATE TABLE mailboxformat ( - fid bigint NOT NULL DEFAULT nextval('mailboxformat_id'), - format varchar(20) NOT NULL, - CONSTRAINT pkey_mailboxformat PRIMARY KEY (fid), - CONSTRAINT ukey_mailboxformat UNIQUE (format) -); --- Insert supported mailbox formats -INSERT INTO mailboxformat(format) VALUES ('maildir'); -INSERT INTO mailboxformat(format) VALUES ('mdbox'); -INSERT INTO mailboxformat(format) VALUES ('sdbox'); - -CREATE TABLE maillocation ( - mid bigint NOT NULL DEFAULT nextval('maillocation_id'), - fid bigint NOT NULL DEFAULT 1, - directory varchar(20) NOT NULL, - extra varchar(1024), - CONSTRAINT pkey_maillocation PRIMARY KEY (mid), - CONSTRAINT fkey_maillocation_fid_mailboxformat FOREIGN KEY (fid) - REFERENCES mailboxformat (fid) -); --- Insert default Maildir-folder name -INSERT INTO maillocation(directory) VALUES ('Maildir'); - -CREATE TABLE quotalimit ( - qid bigint NOT NULL DEFAULT nextval('quotalimit_id'), - bytes bigint NOT NULL, - messages integer NOT NULL DEFAULT 0, - CONSTRAINT pkey_quotalimit PRIMARY KEY (qid), - CONSTRAINT ukey_quotalimit UNIQUE (bytes, messages) -); --- Insert default (non) quota limit -INSERT INTO quotalimit(bytes, messages) VALUES (0, 0); - -CREATE TABLE service_set ( - ssid bigint NOT NULL DEFAULT nextval('service_set_id'), - smtp boolean NOT NULL DEFAULT TRUE, - pop3 boolean NOT NULL DEFAULT TRUE, - imap boolean NOT NULL DEFAULT TRUE, - managesieve boolean NOT NULL DEFAULT TRUE, - CONSTRAINT pkey_service_set PRIMARY KEY (ssid), - CONSTRAINT ukey_service_set UNIQUE (smtp, pop3, imap, managesieve) -); --- Insert all possible service combinations -COPY service_set (smtp, pop3, imap, managesieve) FROM stdin; -TRUE TRUE TRUE TRUE -FALSE TRUE TRUE TRUE -TRUE FALSE TRUE TRUE -FALSE FALSE TRUE TRUE -TRUE TRUE FALSE TRUE -FALSE TRUE FALSE TRUE -TRUE FALSE FALSE TRUE -FALSE FALSE FALSE TRUE -TRUE TRUE TRUE FALSE -FALSE TRUE TRUE FALSE -TRUE FALSE TRUE FALSE -FALSE FALSE TRUE FALSE -TRUE TRUE FALSE FALSE -FALSE TRUE FALSE FALSE -TRUE FALSE FALSE FALSE -FALSE FALSE FALSE FALSE -\. - -CREATE TABLE domain_data ( - gid bigint NOT NULL DEFAULT nextval('domain_gid'), - qid bigint NOT NULL DEFAULT 1, -- default quota limit - ssid bigint NOT NULL DEFAULT 1, -- default service set - tid bigint NOT NULL DEFAULT 1, -- default transport - domaindir varchar(40) NOT NULL, --/srv/mail/$RAND/4294967294 - note text NULL DEFAULT NULL, - CONSTRAINT pkey_domain_data PRIMARY KEY (gid), - CONSTRAINT fkey_domain_data_qid_quotalimit FOREIGN KEY (qid) - REFERENCES quotalimit (qid), - CONSTRAINT fkey_domain_data_ssid_service_set FOREIGN KEY (ssid) - REFERENCES service_set (ssid), - CONSTRAINT fkey_domain_data_tid_transport FOREIGN KEY (tid) - REFERENCES transport (tid) -); - -CREATE TABLE domain_name ( - domainname varchar(255) NOT NULL, - gid bigint NOT NULL, - is_primary boolean NOT NULL, - CONSTRAINT pkey_domain_name PRIMARY KEY (domainname), - CONSTRAINT fkey_domain_name_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - -CREATE TABLE users ( - local_part varchar(64) NOT NULL,-- only localpart w/o '@' - passwd varchar(270) NOT NULL, - name varchar(128) NULL, - uid bigint NOT NULL DEFAULT nextval('users_uid'), - gid bigint NOT NULL, - mid bigint NOT NULL DEFAULT 1, - qid bigint NULL DEFAULT NULL, - ssid bigint NULL DEFAULT NULL, - tid bigint NULL DEFAULT NULL, - note text NULL DEFAULT NULL, - CONSTRAINT pkey_users PRIMARY KEY (local_part, gid), - CONSTRAINT ukey_users_uid UNIQUE (uid), - CONSTRAINT fkey_users_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid), - CONSTRAINT fkey_users_mid_maillocation FOREIGN KEY (mid) - REFERENCES maillocation (mid), - CONSTRAINT fkey_users_qid_quotalimit FOREIGN KEY (qid) - REFERENCES quotalimit (qid), - CONSTRAINT fkey_users_ssid_service_set FOREIGN KEY (ssid) - REFERENCES service_set (ssid), - CONSTRAINT fkey_users_tid_transport FOREIGN KEY (tid) - REFERENCES transport (tid) -); - -CREATE TABLE userquota_11 ( - uid bigint NOT NULL, - path varchar(16) NOT NULL, - current bigint NOT NULL DEFAULT 0, - CONSTRAINT pkey_userquota_11 PRIMARY KEY (uid, path), - CONSTRAINT fkey_userquota_11_uid_users FOREIGN KEY (uid) - REFERENCES users (uid) ON DELETE CASCADE -); - -CREATE TABLE alias ( - gid bigint NOT NULL, - address varchar(64) NOT NULL,-- only localpart w/o '@' - destination varchar(320) NOT NULL, - CONSTRAINT pkey_alias PRIMARY KEY (gid, address, destination), - CONSTRAINT fkey_alias_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - -CREATE TABLE relocated ( - gid bigint NOT NULL, - address varchar(64) NOT NULL, - destination varchar(320) NOT NULL, - CONSTRAINT pkey_relocated PRIMARY KEY (gid, address), - CONSTRAINT fkey_relocated_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - -CREATE TABLE catchall ( - gid bigint NOT NULL, - destination varchar(320) NOT NULL, - CONSTRAINT pkey_catchall PRIMARY KEY (gid, destination), - CONSTRAINT fkey_catchall_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - -CREATE OR REPLACE VIEW postfix_gid AS - SELECT gid, domainname - FROM domain_name; - -CREATE OR REPLACE VIEW vmm_domain_info AS - SELECT gid, count(uid) AS accounts, - (SELECT count(DISTINCT address) - FROM alias - WHERE alias.gid = domain_data.gid) AS aliases, - (SELECT count(gid) - FROM relocated - WHERE relocated.gid = domain_data.gid) AS relocated, - (SELECT count(gid) - FROM domain_name - WHERE domain_name.gid = domain_data.gid - AND NOT domain_name.is_primary) AS aliasdomains, - (SELECT count(gid) - FROM catchall - WHERE catchall.gid = domain_data.gid) AS catchall - FROM domain_data - LEFT JOIN domain_name USING (gid) - LEFT JOIN users USING (gid) - WHERE domain_name.is_primary - GROUP BY gid; - --- ########################################################################## -- - -CREATE LANGUAGE plpgsql; - --- ######################## TYPEs ########################################### -- - --- --- --- Data type for function postfix_virtual_mailbox(varchar, varchar) --- --- -CREATE TYPE address_maildir AS ( - address varchar(320), - maildir text -); --- --- --- Data type for function dovecotpassword(varchar, varchar) --- --- -CREATE TYPE dovecotpassword AS ( - userid varchar(320), - password varchar(270), - smtp boolean, - pop3 boolean, - imap boolean, - managesieve boolean -); --- --- --- Data type for function dovecotquotauser(varchar, varchar) --- --- -CREATE TYPE dovecotquotauser AS ( - userid varchar(320), - uid bigint, - gid bigint, - home text, - mail text, - quota_rule text -); --- --- --- Data type for function dovecotuser(varchar, varchar) --- --- -CREATE TYPE dovecotuser AS ( - userid varchar(320), - uid bigint, - gid bigint, - home text, - mail text -); --- --- --- Data type for functions: postfix_relocated_map(varchar, varchar) --- postfix_virtual_alias_map(varchar, varchar) --- --- -CREATE TYPE recipient_destination AS ( - recipient varchar(320), - destination text -); --- --- --- Data type for function postfix_transport_map(varchar, varchar) --- --- -CREATE TYPE recipient_transport AS ( - recipient varchar(320), - transport text -); --- --- --- Data type for function postfix_virtual_uid_map(varchar, varchar) --- --- -CREATE TYPE recipient_uid AS ( - recipient varchar(320), - uid bigint -); --- --- --- Data type for function postfix_smtpd_sender_login_map(varchar, varchar) --- --- -CREATE TYPE sender_login AS ( - sender varchar(320), - login text -); - --- ######################## TRIGGERs ######################################## -- - -CREATE OR REPLACE FUNCTION domain_primary_trigger() RETURNS TRIGGER AS $$ -DECLARE - primary_count bigint; -BEGIN - SELECT INTO primary_count count(gid) + NEW.is_primary::integer - FROM domain_name - WHERE domain_name.gid = NEW.gid - AND is_primary; - - IF (primary_count > 1) THEN - RAISE EXCEPTION 'There can only be one domain marked as primary.'; - END IF; - - RETURN NEW; -END; -$$ LANGUAGE plpgsql STABLE; - - -CREATE TRIGGER primary_count_ins BEFORE INSERT ON domain_name - FOR EACH ROW EXECUTE PROCEDURE domain_primary_trigger(); - -CREATE TRIGGER primary_count_upd AFTER UPDATE ON domain_name - FOR EACH ROW EXECUTE PROCEDURE domain_primary_trigger(); - - -CREATE OR REPLACE FUNCTION merge_userquota_11() RETURNS TRIGGER AS $$ -BEGIN - UPDATE userquota_11 - SET current = current + NEW.current - WHERE uid = NEW.uid AND path = NEW.path; - IF found THEN - RETURN NULL; - ELSE - RETURN NEW; - END IF; -END; -$$ LANGUAGE plpgsql; - -CREATE TRIGGER mergeuserquota_11 BEFORE INSERT ON userquota_11 - FOR EACH ROW EXECUTE PROCEDURE merge_userquota_11(); - --- ######################## FUNCTIONs ####################################### -- - --- --- --- Parameters (from login name [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: dovecotpassword records --- --- Required access privileges for your dovecot database user: --- GRANT SELECT ON users, domain_name, service_set TO dovecot; --- --- For more details see http://wiki.dovecot.org/AuthDatabase/SQL --- --- -CREATE OR REPLACE FUNCTION dovecotpassword( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotpassword -AS $$ - DECLARE - record dovecotpassword; - userid varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT userid, passwd, smtp, pop3, imap, managesieve - FROM users, service_set, domain_data - WHERE users.gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - AND users.gid = domain_data.gid - AND CASE WHEN - users.ssid IS NOT NULL - THEN - service_set.ssid = users.ssid - ELSE - service_set.ssid = domain_data.ssid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Nearly the same as function dovecotuser below. It returns additionally the --- field quota_rule. --- --- Required access privileges for your dovecot database user: --- GRANT SELECT --- ON users, domain_data, domain_name, maillocation, mailboxformat, --- quotalimit --- TO dovecot; --- --- -CREATE OR REPLACE FUNCTION dovecotquotauser( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotquotauser -AS $$ - DECLARE - record dovecotquotauser; - userid varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT userid, uid, did, domaindir || '/' || uid AS home, - format || ':~/' || directory AS mail, '*:bytes=' || - bytes || ':messages=' || messages AS quota_rule - FROM users, domain_data, mailboxformat, maillocation, quotalimit - WHERE users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - AND mailboxformat.fid = maillocation.fid - AND domain_data.gid = did - AND CASE WHEN - users.qid IS NOT NULL - THEN - quotalimit.qid = users.qid - ELSE - quotalimit.qid = domain_data.qid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from login name [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: dovecotuser records --- --- Required access privileges for your dovecot database user: --- GRANT SELECT --- ON users, domain_data, domain_name, maillocation, mailboxformat --- TO dovecot; --- --- For more details see http://wiki.dovecot.org/UserDatabase --- --- -CREATE OR REPLACE FUNCTION dovecotuser( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotuser -AS $$ - DECLARE - record dovecotuser; - userid varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT userid, uid, did, domaindir || '/' || uid AS home, - format || ':~/' || directory AS mail - FROM users, domain_data, mailboxformat, maillocation - WHERE users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - AND mailboxformat.fid = maillocation.fid - AND domain_data.gid = did - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_destination records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON domain_name, relocated TO postfix; --- --- For more details see postconf(5) section relocated_maps and relocated(5) --- --- -CREATE OR REPLACE FUNCTION postfix_relocated_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_destination -AS $$ - DECLARE - record recipient_destination; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT recipient, destination - FROM relocated - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from _sender_ address (MAIL FROM) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: SASL _login_ names that own _sender_ addresses (MAIL FROM): --- set of sender_login records. --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON domain_name, users, alias TO postfix; --- --- For more details see postconf(5) section smtpd_sender_login_maps --- --- -CREATE OR REPLACE FUNCTION postfix_smtpd_sender_login_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF sender_login -AS $$ - DECLARE - rec sender_login; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - sender varchar(320) := localpart || '@' || the_domain; - BEGIN - -- Get all addresses for 'localpart' in the primary and aliased domains - FOR rec IN - SELECT sender, local_part || '@' || domainname - FROM domain_name, users - WHERE domain_name.gid = did - AND users.gid = did - AND users.local_part = localpart - LOOP - RETURN NEXT rec; - END LOOP; - IF NOT FOUND THEN - -- Loop over the alias addresses for localpart@the_domain - FOR rec IN - SELECT DISTINCT sender, destination - FROM alias - WHERE alias.gid = did - AND alias.address = localpart - LOOP - RETURN NEXT rec; - END LOOP; - END IF; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_transport records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON users, transport, domain_name TO postfix; --- --- For more details see postconf(5) section transport_maps and transport(5) --- --- -CREATE OR REPLACE FUNCTION postfix_transport_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_transport -AS $$ - DECLARE - record recipient_transport; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname = the_domain); - transport_id bigint; - BEGIN - IF did IS NULL THEN - RETURN; - END IF; - - SELECT tid INTO transport_id - FROM users - WHERE gid = did AND local_part = localpart; - - IF transport_id IS NULL THEN - SELECT tid INTO STRICT transport_id - FROM domain_data - WHERE gid = did; - END IF; - - FOR record IN - SELECT recipient, transport - FROM transport - WHERE tid = transport_id - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_destination records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON alias, domain_name TO postfix; --- --- For more details see postconf(5) section virtual_alias_maps and virtual(5) --- --- -CREATE OR REPLACE FUNCTION _interpolate_destination( - IN destination varchar, localpart varchar, IN the_domain varchar) - RETURNS varchar -AS $$ - DECLARE - result varchar(320); - BEGIN - IF position('%' in destination) = 0 THEN - RETURN destination; - END IF; - result := replace(destination, '%n', localpart); - result := replace(result, '%d', the_domain); - result := replace(result, '%=', localpart || '=' || the_domain); - RETURN result; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; - -CREATE OR REPLACE FUNCTION postfix_virtual_alias_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_destination -AS $$ - DECLARE - recordc recipient_destination; - record recipient_destination; - catchall_cursor refcursor; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT recipient, - _interpolate_destination(destination, localpart, the_domain) - FROM alias - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - - IF NOT FOUND THEN - -- There is no matching virtual_alias. If there are no catchall - -- records for this domain, we can just return NULL since Postfix - -- will then later consult mailboxes/relocated itself. But if - -- there is a catchall destination, then it would take precedence - -- over mailboxes/relocated, which is not what we want. Therefore, - -- we must first find out if the query is for an existing mailbox - -- or relocated entry and return the identity mapping if that is - -- the case - OPEN catchall_cursor FOR - SELECT recipient, - _interpolate_destination(destination, localpart, the_domain) - FROM catchall - WHERE gid = did; - FETCH NEXT FROM catchall_cursor INTO recordc; - - IF recordc IS NOT NULL THEN - -- Since there are catchall records for this domain - -- check the mailbox and relocated records and return identity - -- if a matching record exists. - FOR record IN - SELECT recipient, recipient as destination - FROM users - WHERE gid = did - AND local_part = localpart - UNION SELECT recipient, recipient as destination - FROM relocated - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - - IF NOT FOUND THEN - -- There were no records found for mailboxes/relocated, - -- so now we can actually iterate the cursor and populate - -- the return set - LOOP - RETURN NEXT recordc; - FETCH NEXT FROM catchall_cursor INTO recordc; - EXIT WHEN recordc IS NULL; - END LOOP; - END IF; - END IF; - CLOSE catchall_cursor; - END IF; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: address_maildir records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON domain_data,domain_name,maillocation,users TO postfix; --- --- For more details see postconf(5) section virtual_mailbox_maps --- --- -CREATE OR REPLACE FUNCTION postfix_virtual_mailbox_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF address_maildir -AS $$ - DECLARE - rec address_maildir; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - address varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR rec IN - SELECT address, domaindir||'/'||users.uid||'/'||directory||'/' - FROM domain_data, users, maillocation - WHERE domain_data.gid = did - AND users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - LOOP - RETURN NEXT rec; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_uid records --- --- Required access privileges for your postfix database user: --- GRANT SELECT ON users, domain_name TO postfix; --- --- For more details see postconf(5) section virtual_uid_maps --- --- -CREATE OR REPLACE FUNCTION postfix_virtual_uid_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF recipient_uid -AS $$ - DECLARE - record recipient_uid; - recipient varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT recipient, uid - FROM users - WHERE gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; diff -r 659c4476c57c -r b678a1c43027 pgsql/dovecot_update_v1.2+.pgsql --- a/pgsql/dovecot_update_v1.2+.pgsql Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,111 +0,0 @@ --- --- --- Use this file to update the database layout, if you are upgrading your --- Dovecot < v1.2.beta2 to Dovecot >= v1.2.beta2. --- --- IMPORTANT --- This file supports only the current vmm 0.6.0 database layout. --- --- - -SET client_encoding = 'UTF8'; -SET client_min_messages = warning; - - -ALTER TABLE service_set DROP CONSTRAINT ukey_service_set; -ALTER TABLE service_set RENAME managesieve to sieve; -ALTER TABLE service_set - ADD CONSTRAINT ukey_service_set UNIQUE (smtp, pop3, imap, sieve); - - -DROP TRIGGER mergeuserquota_11 ON userquota_11; -DROP FUNCTION merge_userquota_11(); -DROP TABLE userquota_11; - - -DROP TYPE dovecotpassword CASCADE; -CREATE TYPE dovecotpassword AS ( - userid varchar(320), - password varchar(270), - smtp boolean, - pop3 boolean, - imap boolean, - sieve boolean -); - -CREATE OR REPLACE FUNCTION dovecotpassword( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotpassword -AS $$ - DECLARE - record dovecotpassword; - userid varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT userid, passwd, smtp, pop3, imap, sieve - FROM users, service_set, domain_data - WHERE users.gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - AND users.gid = domain_data.gid - AND CASE WHEN - users.ssid IS NOT NULL - THEN - service_set.ssid = users.ssid - ELSE - service_set.ssid = domain_data.ssid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; - - -CREATE TABLE userquota ( - uid bigint NOT NULL, - bytes bigint NOT NULL DEFAULT 0, - messages integer NOT NULL DEFAULT 0, - CONSTRAINT pkey_userquota PRIMARY KEY (uid), - CONSTRAINT fkey_userquota_uid_users FOREIGN KEY (uid) - REFERENCES users (uid) ON DELETE CASCADE -); - -CREATE OR REPLACE FUNCTION merge_userquota() RETURNS TRIGGER AS $$ -BEGIN - IF NEW.messages < 0 OR NEW.messages IS NULL THEN - IF NEW.messages IS NULL THEN - NEW.messages = 0; - ELSE - NEW.messages = -NEW.messages; - END IF; - RETURN NEW; - END IF; - LOOP - UPDATE userquota - SET bytes = bytes + NEW.bytes, messages = messages + NEW.messages - WHERE uid = NEW.uid; - IF found THEN - RETURN NULL; - END IF; - BEGIN - IF NEW.messages = 0 THEN - INSERT INTO userquota VALUES (NEW.uid, NEW.bytes, NULL); - ELSE - INSERT INTO userquota VALUES (NEW.uid, NEW.bytes, -NEW.messages); - END IF; - RETURN NULL; - EXCEPTION - WHEN unique_violation THEN - -- do nothing, and loop to try the UPDATE again - WHEN foreign_key_violation THEN - -- break the loop: a non matching uid means no such user - RETURN NULL; - END; - END LOOP; -END; -$$ LANGUAGE plpgsql; - -CREATE TRIGGER mergeuserquota BEFORE INSERT ON userquota - FOR EACH ROW EXECUTE PROCEDURE merge_userquota(); diff -r 659c4476c57c -r b678a1c43027 pgsql/set-permissions.py --- a/pgsql/set-permissions.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,169 +0,0 @@ -#!/usr/bin/env python -# coding: utf-8 -# Copyright 2012 - 2014, Pascal Volk -# See COPYING for distribution information. - -""" - Use this script in order to set database permissions for your Dovecot - and Postfix database users. - - Run `python set-permissions.py -h` for details. -""" - -import getpass -import sys - -from optparse import OptionParser - -has_psycopg2 = False -try: - import psycopg2 - has_psycopg2 = True -except ImportError: - try: - from pyPgSQL import PgSQL - except ImportError: - sys.stderr.write('error: no suitable database module found\n') - raise SystemExit(1) - -if has_psycopg2: - DBErr = psycopg2.DatabaseError -else: - DBErr = PgSQL.libpq.DatabaseError - - -def check_opts(opts, err_hdlr): - if not opts.postfix: - err_hdlr('missing Postfix database user name') - if not opts.dovecot: - err_hdlr('missing Dovecot database user name') - if opts.askp: - opts.dbpass = getpass.getpass() - - -def get_dbh(database, user, password, host, port): - if has_psycopg2: - return psycopg2.connect(database=database, user=user, - password=password, host=host, port=port) - return PgSQL.connect(user=user, password=password, host=host, - database=database, port=port) - - -def get_optparser(): - descr = 'Set permissions for Dovecot and Postfix in the vmm database.' - usage = 'usage: %prog OPTIONS' - parser = OptionParser(description=descr, usage=usage) - parser.add_option('-a', '--askpass', dest='askp', default=False, - action='store_true', help='Prompt for the database password.') - parser.add_option('-H', '--host', dest='host', metavar='HOST', - default=None, - help='Hostname or IP address of the database server. Leave ' + - 'blank in order to use the default Unix-domain socket.') - parser.add_option('-n', '--name', dest='name', metavar='NAME', - default='mailsys', - help='Specifies the name of the database to connect to. ' + - 'Default: %default') - parser.add_option('-p', '--pass', dest="dbpass", metavar='PASS', - default=None, help='Password for the database connection.') - parser.add_option('-P', '--port', dest='port', metavar='PORT', type='int', - default=5432, - help='Specifies the TCP port or the local Unix-domain socket ' + - 'file extension on which the server is listening for ' + - 'connections. Default: %default') - parser.add_option('-U', '--user', dest='user', metavar='USER', - default=getpass.getuser(), - help='Connect to the database as the user USER instead of the ' + - 'default: %default') - parser.add_option('-D', '--dovecot', dest='dovecot', metavar='USER', - default='dovecot', - help='Database user name of the Dovecot database user. Default: ' + - '%default') - parser.add_option('-M', '--postfix', dest='postfix', metavar='USER', - default='postfix', - help='Database user name of the Postfix (MTA) database user. ' + - 'Default: %default') - return parser - - -def set_permissions(dbh, dc_vers, dovecot, postfix): - dc_rw = ('userquota_11', 'userquota')[dc_vers == 12] - dbc = dbh.cursor() - dbc.execute('GRANT SELECT ON domain_data, domain_name, mailboxformat, ' - 'maillocation, quotalimit, service_set, users TO %s' % dovecot) - dbc.execute('GRANT SELECT, INSERT, UPDATE, DELETE ON %s TO %s' % - (dc_rw, dovecot)) - dbc.execute('GRANT SELECT ON alias, catchall, domain_data, domain_name, ' - 'maillocation, postfix_gid, relocated, transport, users TO %s' - % postfix) - dbc.close() - - -def set_permissions84(dbh, dc_vers, dovecot, postfix): - dc_rw_tbls = ('userquota_11', 'userquota')[dc_vers == 12] - dc_ro_tbls = 'mailboxformat, maillocation, service_set, quotalimit' - pf_ro_tbls = 'alias, catchall, postfix_gid, relocated, transport' - db = dict(dovecot=dovecot, postfix=postfix) - db['dovecot_tbls'] = { - 'domain_data': 'domaindir, gid, qid, ssid', - 'domain_name': 'domainname, gid', - 'users': 'gid, local_part, mid, passwd, qid, ssid, uid', - } - db['postfix_tbls'] = { - 'domain_data': 'domaindir, gid, tid', - 'domain_name': 'domainname, gid', - 'maillocation': 'directory, mid', - 'users': 'gid, local_part, mid, tid, uid', - } - dbc = dbh.cursor() - dbc.execute('GRANT SELECT, INSERT, UPDATE, DELETE ON %s TO %s' % - (dc_rw_tbls, db['dovecot'])) - dbc.execute('GRANT SELECT ON %s TO %s' % (dc_ro_tbls, db['dovecot'])) - dbc.execute('GRANT SELECT ON %s TO %s' % (pf_ro_tbls, db['postfix'])) - for table, columns in db['dovecot_tbls'].iteritems(): - dbc.execute('GRANT SELECT (%s) ON %s TO %s' % (columns, table, - db['dovecot'])) - for table, columns in db['postfix_tbls'].iteritems(): - dbc.execute('GRANT SELECT (%s) ON %s TO %s' % (columns, table, - db['postfix'])) - dbc.close() - - -def set_versions(dbh, versions): - dbc = dbh.cursor() - if hasattr(dbh, 'server_version'): - versions['pgsql'] = dbh.server_version - else: - try: - dbc.execute("SELECT current_setting('server_version_num')") - versions['pgsql'] = int(dbc.fetchone()[0]) - except DBErr: - versions['pgsql'] = 80199 - dbc.execute("SELECT relname FROM pg_stat_user_tables WHERE relname LIKE " - "'userquota%'") - res = dbc.fetchall() - dbc.close() - tbls = [tbl[0] for tbl in res] - if 'userquota' in tbls: - versions['dovecot'] = 12 - elif 'userquota_11' in tbls: - versions['dovecot'] = 11 - else: - sys.stderr.write('error: no userquota table found\nis "' + dbh.dsn + - '" correct? is the database up to date?\n') - dbh.close() - raise SystemExit(1) - - -if __name__ == '__main__': - optparser = get_optparser() - opts, args = optparser.parse_args() - check_opts(opts, optparser.error) - dbh = get_dbh(opts.name, opts.user, opts.dbpass, opts.host, opts.port) - versions = {} - set_versions(dbh, versions) - if versions['pgsql'] < 80400: - set_permissions(dbh, versions['dovecot'], opts.dovecot, opts.postfix) - else: - set_permissions84(dbh, versions['dovecot'], opts.dovecot, opts.postfix) - dbh.commit() - dbh.close() diff -r 659c4476c57c -r b678a1c43027 pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql --- a/pgsql/update_tables_0.5.x-0.6-dovecot-1.2.x.pgsql Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,680 +0,0 @@ -SET client_encoding = 'UTF8'; -SET client_min_messages = warning; - --- --- --- Create the new service_set table and insert all possible combinations --- -- -CREATE SEQUENCE service_set_id; - -CREATE TABLE service_set ( - ssid bigint NOT NULL DEFAULT nextval('service_set_id'), - smtp boolean NOT NULL DEFAULT TRUE, - pop3 boolean NOT NULL DEFAULT TRUE, - imap boolean NOT NULL DEFAULT TRUE, - sieve boolean NOT NULL DEFAULT TRUE, - CONSTRAINT pkey_service_set PRIMARY KEY (ssid), - CONSTRAINT ukey_service_set UNIQUE (smtp, pop3, imap, sieve) -); - -COPY service_set (smtp, pop3, imap, sieve) FROM stdin; -TRUE TRUE TRUE TRUE -FALSE TRUE TRUE TRUE -TRUE FALSE TRUE TRUE -FALSE FALSE TRUE TRUE -TRUE TRUE FALSE TRUE -FALSE TRUE FALSE TRUE -TRUE FALSE FALSE TRUE -FALSE FALSE FALSE TRUE -TRUE TRUE TRUE FALSE -FALSE TRUE TRUE FALSE -TRUE FALSE TRUE FALSE -FALSE FALSE TRUE FALSE -TRUE TRUE FALSE FALSE -FALSE TRUE FALSE FALSE -TRUE FALSE FALSE FALSE -FALSE FALSE FALSE FALSE -\. - --- --- --- Drop the obsolete VIEWs, we've functions now. --- --- -DROP VIEW dovecot_user; -DROP VIEW dovecot_password; -DROP VIEW postfix_alias; -DROP VIEW postfix_maildir; -DROP VIEW postfix_relocated; -DROP VIEW postfix_transport; -DROP VIEW postfix_uid; --- the vmm_domain_info view will be restored later -DROP VIEW vmm_domain_info; - -CREATE SEQUENCE mailboxformat_id; -CREATE SEQUENCE quotalimit_id; - -CREATE TABLE mailboxformat ( - fid bigint NOT NULL DEFAULT nextval('mailboxformat_id'), - format varchar(20) NOT NULL, - CONSTRAINT pkey_mailboxformat PRIMARY KEY (fid), - CONSTRAINT ukey_mailboxformat UNIQUE (format) -); --- Insert supported mailbox formats -INSERT INTO mailboxformat(format) VALUES ('maildir'); -INSERT INTO mailboxformat(format) VALUES ('mdbox'); -INSERT INTO mailboxformat(format) VALUES ('sdbox'); - --- Adjust maillocation table -ALTER TABLE maillocation DROP CONSTRAINT ukey_maillocation; -ALTER TABLE maillocation RENAME COLUMN maillocation TO directory; -ALTER TABLE maillocation - ADD COLUMN fid bigint NOT NULL DEFAULT 1, - ADD COLUMN extra varchar(1024); -ALTER TABLE maillocation ADD CONSTRAINT fkey_maillocation_fid_mailboxformat - FOREIGN KEY (fid) REFERENCES mailboxformat (fid); - -ALTER TABLE users ALTER COLUMN passwd TYPE varchar(270); - --- --- --- Add quota stuff --- --- -CREATE TABLE quotalimit ( - qid bigint NOT NULL DEFAULT nextval('quotalimit_id'), - bytes bigint NOT NULL, - messages integer NOT NULL DEFAULT 0, - CONSTRAINT pkey_quotalimit PRIMARY KEY (qid), - CONSTRAINT ukey_quotalimit UNIQUE (bytes, messages) -); --- Insert default (non) quota limit -INSERT INTO quotalimit(bytes, messages) VALUES (0, 0); - --- Adjust tables (quota) -ALTER TABLE domain_data ADD COLUMN qid bigint NOT NULL DEFAULT 1; -ALTER TABLE domain_data ADD CONSTRAINT fkey_domain_data_qid_quotalimit - FOREIGN KEY (qid) REFERENCES quotalimit (qid); - -ALTER TABLE users ADD COLUMN qid bigint NULL DEFAULT NULL; -ALTER TABLE users ADD CONSTRAINT fkey_users_qid_quotalimit - FOREIGN KEY (qid) REFERENCES quotalimit (qid); - -CREATE TABLE userquota ( - uid bigint NOT NULL, - bytes bigint NOT NULL DEFAULT 0, - messages integer NOT NULL DEFAULT 0, - CONSTRAINT pkey_userquota PRIMARY KEY (uid), - CONSTRAINT fkey_userquota_uid_users FOREIGN KEY (uid) - REFERENCES users (uid) ON DELETE CASCADE -); - -CREATE OR REPLACE FUNCTION merge_userquota() RETURNS TRIGGER AS $$ -BEGIN - IF NEW.messages < 0 OR NEW.messages IS NULL THEN - IF NEW.messages IS NULL THEN - NEW.messages = 0; - ELSE - NEW.messages = -NEW.messages; - END IF; - RETURN NEW; - END IF; - LOOP - UPDATE userquota - SET bytes = bytes + NEW.bytes, messages = messages + NEW.messages - WHERE uid = NEW.uid; - IF found THEN - RETURN NULL; - END IF; - BEGIN - IF NEW.messages = 0 THEN - INSERT INTO userquota VALUES (NEW.uid, NEW.bytes, NULL); - ELSE - INSERT INTO userquota VALUES (NEW.uid, NEW.bytes, -NEW.messages); - END IF; - RETURN NULL; - EXCEPTION - WHEN unique_violation THEN - -- do nothing, and loop to try the UPDATE again - WHEN foreign_key_violation THEN - -- break the loop: a non matching uid means no such user - RETURN NULL; - END; - END LOOP; -END; -$$ LANGUAGE plpgsql; - -CREATE TRIGGER mergeuserquota BEFORE INSERT ON userquota - FOR EACH ROW EXECUTE PROCEDURE merge_userquota(); - --- Adjust tables (services) -ALTER TABLE domain_data ADD COLUMN ssid bigint NOT NULL DEFAULT 1; -ALTER TABLE domain_data ADD CONSTRAINT fkey_domain_data_ssid_service_set - FOREIGN KEY (ssid) REFERENCES service_set (ssid); - -ALTER TABLE users ADD COLUMN ssid bigint NULL DEFAULT NULL; --- save current service sets -UPDATE users u - SET ssid = ss.ssid - FROM service_set ss - WHERE ss.smtp = u.smtp - AND ss.pop3 = u.pop3 - AND ss.imap = u.imap - AND ss.sieve = u.sieve; - -ALTER TABLE users DROP COLUMN smtp; -ALTER TABLE users DROP COLUMN pop3; -ALTER TABLE users DROP COLUMN imap; -ALTER TABLE users DROP COLUMN sieve; -ALTER TABLE users ADD CONSTRAINT fkey_users_ssid_service_set - FOREIGN KEY (ssid) REFERENCES service_set (ssid); - --- --- --- Catchall --- --- - -CREATE TABLE catchall ( - gid bigint NOT NULL, - destination varchar(320) NOT NULL, - CONSTRAINT pkey_catchall PRIMARY KEY (gid, destination), - CONSTRAINT fkey_catchall_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - --- --- --- Quota/Service/Transport inheritance --- --- -ALTER TABLE users ALTER COLUMN tid DROP NOT NULL; -ALTER TABLE users ALTER COLUMN tid SET DEFAULT NULL; --- The qid and ssid columns have already been defined accordingly above. --- The rest of the logic will take place in the functions. - --- While qid and ssid are new and it's perfectly okay for existing users to --- get NULL values (i.e. inherit from the domain's default), tid existed in --- vmm 0.5.x. A sensible way forward seems thus to NULL all user records' tid --- fields where the tid duplicates the value stored in the domain's record. -UPDATE users - SET tid = NULL - WHERE tid = (SELECT tid - FROM domain_data - WHERE domain_data.gid = users.gid); - --- --- --- Account/domain notes --- --- - -ALTER TABLE users ADD COLUMN note text NULL DEFAULT NULL; -ALTER TABLE domain_data ADD COLUMN note text NULL DEFAULT NULL; - --- --- --- Restore view --- --- -CREATE VIEW vmm_domain_info AS - SELECT gid, count(uid) AS accounts, - (SELECT count(DISTINCT address) - FROM alias - WHERE alias.gid = domain_data.gid) AS aliases, - (SELECT count(gid) - FROM relocated - WHERE relocated.gid = domain_data.gid) AS relocated, - (SELECT count(gid) - FROM domain_name - WHERE domain_name.gid = domain_data.gid - AND NOT domain_name.is_primary) AS aliasdomains, - (SELECT count(gid) - FROM catchall - WHERE catchall.gid = domain_data.gid) AS catchall - FROM domain_data - LEFT JOIN domain_name USING (gid) - LEFT JOIN users USING (gid) - WHERE domain_name.is_primary - GROUP BY gid; - --- --- --- Drop all known v0.5 types (the dirty way) --- --- -DROP TYPE address_maildir CASCADE; -DROP TYPE dovecotpassword CASCADE; -DROP TYPE dovecotuser CASCADE; -DROP TYPE recipient_destination CASCADE; -DROP TYPE recipient_transport CASCADE; -DROP TYPE recipient_uid CASCADE; -DROP TYPE sender_login CASCADE; - --- ######################## TYPEs ########################################### -- - --- --- --- Data type for function postfix_virtual_mailbox(varchar, varchar) --- --- -CREATE TYPE address_maildir AS ( - address varchar(320), - maildir text -); --- --- --- Data type for function dovecotpassword(varchar, varchar) --- --- -CREATE TYPE dovecotpassword AS ( - userid varchar(320), - password varchar(270), - smtp boolean, - pop3 boolean, - imap boolean, - sieve boolean -); --- --- --- Data type for function dovecotquotauser(varchar, varchar) --- --- -CREATE TYPE dovecotquotauser AS ( - userid varchar(320), - uid bigint, - gid bigint, - home text, - mail text, - quota_rule text -); --- --- --- Data type for function dovecotuser(varchar, varchar) --- --- -CREATE TYPE dovecotuser AS ( - userid varchar(320), - uid bigint, - gid bigint, - home text, - mail text -); --- --- --- Data type for functions: postfix_relocated_map(varchar, varchar) --- postfix_virtual_alias_map(varchar, varchar) --- --- -CREATE TYPE recipient_destination AS ( - recipient varchar(320), - destination text -); --- --- --- Data type for function postfix_transport_map(varchar, varchar) --- --- -CREATE TYPE recipient_transport AS ( - recipient varchar(320), - transport text -); --- --- --- Data type for function postfix_virtual_uid_map(varchar, varchar) --- --- -CREATE TYPE recipient_uid AS ( - recipient varchar(320), - uid bigint -); --- --- --- Data type for function postfix_smtpd_sender_login_map(varchar, varchar) --- --- -CREATE TYPE sender_login AS ( - sender varchar(320), - login text -); - --- ######################## FUNCTIONs ####################################### -- - --- --- --- Parameters (from login name [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: dovecotpassword records --- --- -CREATE OR REPLACE FUNCTION dovecotpassword( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotpassword -AS $$ - DECLARE - record dovecotpassword; - userid varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT userid, passwd, smtp, pop3, imap, sieve - FROM users, service_set, domain_data - WHERE users.gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - AND users.gid = domain_data.gid - AND CASE WHEN - users.ssid IS NOT NULL - THEN - service_set.ssid = users.ssid - ELSE - service_set.ssid = domain_data.ssid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Nearly the same as function dovecotuser below. It returns additionally the --- field quota_rule. --- --- -CREATE OR REPLACE FUNCTION dovecotquotauser( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotquotauser -AS $$ - DECLARE - record dovecotquotauser; - userid varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT userid, uid, did, domaindir || '/' || uid AS home, - format || ':~/' || directory AS mail, '*:bytes=' || - bytes || ':messages=' || messages AS quota_rule - FROM users, domain_data, mailboxformat, maillocation, quotalimit - WHERE users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - AND mailboxformat.fid = maillocation.fid - AND domain_data.gid = did - AND CASE WHEN - users.qid IS NOT NULL - THEN - quotalimit.qid = users.qid - ELSE - quotalimit.qid = domain_data.qid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from login name [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: dovecotuser records --- --- -CREATE OR REPLACE FUNCTION dovecotuser( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotuser -AS $$ - DECLARE - record dovecotuser; - userid varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT userid, uid, did, domaindir || '/' || uid AS home, - format || ':~/' || directory AS mail - FROM users, domain_data, mailboxformat, maillocation - WHERE users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - AND mailboxformat.fid = maillocation.fid - AND domain_data.gid = did - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_destination records --- --- -CREATE OR REPLACE FUNCTION postfix_relocated_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_destination -AS $$ - DECLARE - record recipient_destination; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT recipient, destination - FROM relocated - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from _sender_ address (MAIL FROM) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: SASL _login_ names that own _sender_ addresses (MAIL FROM): --- set of sender_login records. --- --- -CREATE OR REPLACE FUNCTION postfix_smtpd_sender_login_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF sender_login -AS $$ - DECLARE - rec sender_login; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - sender varchar(320) := localpart || '@' || the_domain; - BEGIN - -- Get all addresses for 'localpart' in the primary and aliased domains - FOR rec IN - SELECT sender, local_part || '@' || domainname - FROM domain_name, users - WHERE domain_name.gid = did - AND users.gid = did - AND users.local_part = localpart - LOOP - RETURN NEXT rec; - END LOOP; - IF NOT FOUND THEN - -- Loop over the alias addresses for localpart@the_domain - FOR rec IN - SELECT DISTINCT sender, destination - FROM alias - WHERE alias.gid = did - AND alias.address = localpart - LOOP - RETURN NEXT rec; - END LOOP; - END IF; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_transport records --- --- -CREATE OR REPLACE FUNCTION postfix_transport_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_transport -AS $$ - DECLARE - record recipient_transport; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname = the_domain); - transport_id bigint; - BEGIN - IF did IS NULL THEN - RETURN; - END IF; - - SELECT tid INTO transport_id - FROM users - WHERE gid = did AND local_part = localpart; - - IF transport_id IS NULL THEN - SELECT tid INTO STRICT transport_id - FROM domain_data - WHERE gid = did; - END IF; - - FOR record IN - SELECT recipient, transport - FROM transport - WHERE tid = transport_id - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_destination records --- --- -CREATE OR REPLACE FUNCTION _interpolate_destination( - IN destination varchar, localpart varchar, IN the_domain varchar) - RETURNS varchar -AS $$ - DECLARE - result varchar(320); - BEGIN - IF position('%' in destination) = 0 THEN - RETURN destination; - END IF; - result := replace(destination, '%n', localpart); - result := replace(result, '%d', the_domain); - result := replace(result, '%=', localpart || '=' || the_domain); - RETURN result; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; - -CREATE OR REPLACE FUNCTION postfix_virtual_alias_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_destination -AS $$ - DECLARE - recordc recipient_destination; - record recipient_destination; - catchall_cursor refcursor; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT recipient, - _interpolate_destination(destination, localpart, the_domain) - FROM alias - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - - IF NOT FOUND THEN - -- There is no matching virtual_alias. If there are no catchall - -- records for this domain, we can just return NULL since Postfix - -- will then later consult mailboxes/relocated itself. But if - -- there is a catchall destination, then it would take precedence - -- over mailboxes/relocated, which is not what we want. Therefore, - -- we must first find out if the query is for an existing mailbox - -- or relocated entry and return the identity mapping if that is - -- the case - OPEN catchall_cursor FOR - SELECT recipient, - _interpolate_destination(destination, localpart, the_domain) - FROM catchall - WHERE gid = did; - FETCH NEXT FROM catchall_cursor INTO recordc; - - IF recordc IS NOT NULL THEN - -- Since there are catchall records for this domain - -- check the mailbox and relocated records and return identity - -- if a matching record exists. - FOR record IN - SELECT recipient, recipient as destination - FROM users - WHERE gid = did - AND local_part = localpart - UNION SELECT recipient, recipient as destination - FROM relocated - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - - IF NOT FOUND THEN - -- There were no records found for mailboxes/relocated, - -- so now we can actually iterate the cursor and populate - -- the return set - LOOP - RETURN NEXT recordc; - FETCH NEXT FROM catchall_cursor INTO recordc; - EXIT WHEN recordc IS NULL; - END LOOP; - END IF; - END IF; - CLOSE catchall_cursor; - END IF; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: address_maildir records --- --- -CREATE OR REPLACE FUNCTION postfix_virtual_mailbox_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF address_maildir -AS $$ - DECLARE - rec address_maildir; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - address varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR rec IN - SELECT address, domaindir||'/'||users.uid||'/'||directory||'/' - FROM domain_data, users, maillocation - WHERE domain_data.gid = did - AND users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - LOOP - RETURN NEXT rec; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_uid records --- --- -CREATE OR REPLACE FUNCTION postfix_virtual_uid_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF recipient_uid -AS $$ - DECLARE - record recipient_uid; - recipient varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT recipient, uid - FROM users - WHERE gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; diff -r 659c4476c57c -r b678a1c43027 pgsql/update_tables_0.5.x-0.6.pgsql --- a/pgsql/update_tables_0.5.x-0.6.pgsql Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,658 +0,0 @@ -SET client_encoding = 'UTF8'; -SET client_min_messages = warning; - --- --- --- Create the new service_set table and insert all possible combinations --- -- -CREATE SEQUENCE service_set_id; - -CREATE TABLE service_set ( - ssid bigint NOT NULL DEFAULT nextval('service_set_id'), - smtp boolean NOT NULL DEFAULT TRUE, - pop3 boolean NOT NULL DEFAULT TRUE, - imap boolean NOT NULL DEFAULT TRUE, - managesieve boolean NOT NULL DEFAULT TRUE, - CONSTRAINT pkey_service_set PRIMARY KEY (ssid), - CONSTRAINT ukey_service_set UNIQUE (smtp, pop3, imap, managesieve) -); - -COPY service_set (smtp, pop3, imap, managesieve) FROM stdin; -TRUE TRUE TRUE TRUE -FALSE TRUE TRUE TRUE -TRUE FALSE TRUE TRUE -FALSE FALSE TRUE TRUE -TRUE TRUE FALSE TRUE -FALSE TRUE FALSE TRUE -TRUE FALSE FALSE TRUE -FALSE FALSE FALSE TRUE -TRUE TRUE TRUE FALSE -FALSE TRUE TRUE FALSE -TRUE FALSE TRUE FALSE -FALSE FALSE TRUE FALSE -TRUE TRUE FALSE FALSE -FALSE TRUE FALSE FALSE -TRUE FALSE FALSE FALSE -FALSE FALSE FALSE FALSE -\. - --- --- --- Drop the obsolete VIEWs, we've functions now. --- --- -DROP VIEW dovecot_user; -DROP VIEW dovecot_password; -DROP VIEW postfix_alias; -DROP VIEW postfix_maildir; -DROP VIEW postfix_relocated; -DROP VIEW postfix_transport; -DROP VIEW postfix_uid; --- the vmm_domain_info view will be restored later -DROP VIEW vmm_domain_info; - -CREATE SEQUENCE mailboxformat_id; -CREATE SEQUENCE quotalimit_id; - -CREATE TABLE mailboxformat ( - fid bigint NOT NULL DEFAULT nextval('mailboxformat_id'), - format varchar(20) NOT NULL, - CONSTRAINT pkey_mailboxformat PRIMARY KEY (fid), - CONSTRAINT ukey_mailboxformat UNIQUE (format) -); --- Insert supported mailbox formats -INSERT INTO mailboxformat(format) VALUES ('maildir'); -INSERT INTO mailboxformat(format) VALUES ('mdbox'); -INSERT INTO mailboxformat(format) VALUES ('sdbox'); - --- Adjust maillocation table -ALTER TABLE maillocation DROP CONSTRAINT ukey_maillocation; -ALTER TABLE maillocation RENAME COLUMN maillocation TO directory; -ALTER TABLE maillocation - ADD COLUMN fid bigint NOT NULL DEFAULT 1, - ADD COLUMN extra varchar(1024); -ALTER TABLE maillocation ADD CONSTRAINT fkey_maillocation_fid_mailboxformat - FOREIGN KEY (fid) REFERENCES mailboxformat (fid); - -ALTER TABLE users ALTER COLUMN passwd TYPE varchar(270); - --- --- --- Add quota stuff --- --- -CREATE TABLE quotalimit ( - qid bigint NOT NULL DEFAULT nextval('quotalimit_id'), - bytes bigint NOT NULL, - messages integer NOT NULL DEFAULT 0, - CONSTRAINT pkey_quotalimit PRIMARY KEY (qid), - CONSTRAINT ukey_quotalimit UNIQUE (bytes, messages) -); --- Insert default (non) quota limit -INSERT INTO quotalimit(bytes, messages) VALUES (0, 0); - --- Adjust tables (quota) -ALTER TABLE domain_data ADD COLUMN qid bigint NOT NULL DEFAULT 1; -ALTER TABLE domain_data ADD CONSTRAINT fkey_domain_data_qid_quotalimit - FOREIGN KEY (qid) REFERENCES quotalimit (qid); - -ALTER TABLE users ADD COLUMN qid bigint NULL DEFAULT NULL; -ALTER TABLE users ADD CONSTRAINT fkey_users_qid_quotalimit - FOREIGN KEY (qid) REFERENCES quotalimit (qid); - -CREATE TABLE userquota_11 ( - uid bigint NOT NULL, - path varchar(16) NOT NULL, - current bigint NOT NULL DEFAULT 0, - CONSTRAINT pkey_userquota_11 PRIMARY KEY (uid, path), - CONSTRAINT fkey_userquota_11_uid_users FOREIGN KEY (uid) - REFERENCES users (uid) ON DELETE CASCADE -); - -CREATE OR REPLACE FUNCTION merge_userquota_11() RETURNS TRIGGER AS $$ -BEGIN - UPDATE userquota_11 - SET current = current + NEW.current - WHERE uid = NEW.uid AND path = NEW.path; - IF found THEN - RETURN NULL; - ELSE - RETURN NEW; - END IF; -END; -$$ LANGUAGE plpgsql; - -CREATE TRIGGER mergeuserquota_11 BEFORE INSERT ON userquota_11 - FOR EACH ROW EXECUTE PROCEDURE merge_userquota_11(); - --- Adjust tables (services) -ALTER TABLE domain_data ADD COLUMN ssid bigint NOT NULL DEFAULT 1; -ALTER TABLE domain_data ADD CONSTRAINT fkey_domain_data_ssid_service_set - FOREIGN KEY (ssid) REFERENCES service_set (ssid); - -ALTER TABLE users ADD COLUMN ssid bigint NULL DEFAULT NULL; --- save current service sets -UPDATE users u - SET ssid = ss.ssid - FROM service_set ss - WHERE ss.smtp = u.smtp - AND ss.pop3 = u.pop3 - AND ss.imap = u.imap - AND ss.managesieve = u.managesieve; - -ALTER TABLE users DROP COLUMN smtp; -ALTER TABLE users DROP COLUMN pop3; -ALTER TABLE users DROP COLUMN imap; -ALTER TABLE users DROP COLUMN managesieve; -ALTER TABLE users ADD CONSTRAINT fkey_users_ssid_service_set - FOREIGN KEY (ssid) REFERENCES service_set (ssid); - --- --- --- Catchall --- --- --- Quota/Service/Transport inheritance --- --- -ALTER TABLE users ALTER COLUMN tid DROP NOT NULL; -ALTER TABLE users ALTER COLUMN tid SET DEFAULT NULL; --- The qid and ssid columns have already been defined accordingly above. --- The rest of the logic will take place in the functions. - --- While qid and ssid are new and it's perfectly okay for existing users to --- get NULL values (i.e. inherit from the domain's default), tid existed in --- vmm 0.5.x. A sensible way forward seems thus to NULL all user records' tid --- fields where the tid duplicates the value stored in the domain's record. -UPDATE users - SET tid = NULL - WHERE tid = (SELECT tid - FROM domain_data - WHERE domain_data.gid = users.gid); - --- --- - -CREATE TABLE catchall ( - gid bigint NOT NULL, - destination varchar(320) NOT NULL, - CONSTRAINT pkey_catchall PRIMARY KEY (gid, destination), - CONSTRAINT fkey_catchall_gid_domain_data FOREIGN KEY (gid) - REFERENCES domain_data (gid) -); - --- --- --- Account/domain notes --- --- - -ALTER TABLE users ADD COLUMN note text NULL DEFAULT NULL; -ALTER TABLE domain_data ADD COLUMN note text NULL DEFAULT NULL; - --- --- --- Restore view --- --- -CREATE VIEW vmm_domain_info AS - SELECT gid, count(uid) AS accounts, - (SELECT count(DISTINCT address) - FROM alias - WHERE alias.gid = domain_data.gid) AS aliases, - (SELECT count(gid) - FROM relocated - WHERE relocated.gid = domain_data.gid) AS relocated, - (SELECT count(gid) - FROM domain_name - WHERE domain_name.gid = domain_data.gid - AND NOT domain_name.is_primary) AS aliasdomains, - (SELECT count(gid) - FROM catchall - WHERE catchall.gid = domain_data.gid) AS catchall - FROM domain_data - LEFT JOIN domain_name USING (gid) - LEFT JOIN users USING (gid) - WHERE domain_name.is_primary - GROUP BY gid; - --- --- --- Drop all known v0.5 types (the dirty way) --- --- -DROP TYPE address_maildir CASCADE; -DROP TYPE dovecotpassword CASCADE; -DROP TYPE dovecotuser CASCADE; -DROP TYPE recipient_destination CASCADE; -DROP TYPE recipient_transport CASCADE; -DROP TYPE recipient_uid CASCADE; -DROP TYPE sender_login CASCADE; - --- ######################## TYPEs ########################################### -- - --- --- --- Data type for function postfix_virtual_mailbox(varchar, varchar) --- --- -CREATE TYPE address_maildir AS ( - address varchar(320), - maildir text -); --- --- --- Data type for function dovecotpassword(varchar, varchar) --- --- -CREATE TYPE dovecotpassword AS ( - userid varchar(320), - password varchar(270), - smtp boolean, - pop3 boolean, - imap boolean, - managesieve boolean -); --- --- --- Data type for function dovecotquotauser(varchar, varchar) --- --- -CREATE TYPE dovecotquotauser AS ( - userid varchar(320), - uid bigint, - gid bigint, - home text, - mail text, - quota_rule text -); --- --- --- Data type for function dovecotuser(varchar, varchar) --- --- -CREATE TYPE dovecotuser AS ( - userid varchar(320), - uid bigint, - gid bigint, - home text, - mail text -); --- --- --- Data type for functions: postfix_relocated_map(varchar, varchar) --- postfix_virtual_alias_map(varchar, varchar) --- --- -CREATE TYPE recipient_destination AS ( - recipient varchar(320), - destination text -); --- --- --- Data type for function postfix_transport_map(varchar, varchar) --- --- -CREATE TYPE recipient_transport AS ( - recipient varchar(320), - transport text -); --- --- --- Data type for function postfix_virtual_uid_map(varchar, varchar) --- --- -CREATE TYPE recipient_uid AS ( - recipient varchar(320), - uid bigint -); --- --- --- Data type for function postfix_smtpd_sender_login_map(varchar, varchar) --- --- -CREATE TYPE sender_login AS ( - sender varchar(320), - login text -); - --- ######################## FUNCTIONs ####################################### -- - --- --- --- Parameters (from login name [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: dovecotpassword records --- --- -CREATE OR REPLACE FUNCTION dovecotpassword( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotpassword -AS $$ - DECLARE - record dovecotpassword; - userid varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT userid, passwd, smtp, pop3, imap, managesieve - FROM users, service_set, domain_data - WHERE users.gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - AND users.gid = domain_data.gid - AND CASE WHEN - users.ssid IS NOT NULL - THEN - service_set.ssid = users.ssid - ELSE - service_set.ssid = domain_data.ssid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Nearly the same as function dovecotuser below. It returns additionally the --- field quota_rule. --- --- -CREATE OR REPLACE FUNCTION dovecotquotauser( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotquotauser -AS $$ - DECLARE - record dovecotquotauser; - userid varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT userid, uid, did, domaindir || '/' || uid AS home, - format || ':~/' || directory AS mail, '*:bytes=' || - bytes || ':messages=' || messages AS quota_rule - FROM users, domain_data, mailboxformat, maillocation, quotalimit - WHERE users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - AND mailboxformat.fid = maillocation.fid - AND domain_data.gid = did - AND CASE WHEN - users.qid IS NOT NULL - THEN - quotalimit.qid = users.qid - ELSE - quotalimit.qid = domain_data.qid - END - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from login name [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: dovecotuser records --- --- -CREATE OR REPLACE FUNCTION dovecotuser( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF dovecotuser -AS $$ - DECLARE - record dovecotuser; - userid varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT userid, uid, did, domaindir || '/' || uid AS home, - format || ':~/' || directory AS mail - FROM users, domain_data, mailboxformat, maillocation - WHERE users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - AND mailboxformat.fid = maillocation.fid - AND domain_data.gid = did - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_destination records --- --- -CREATE OR REPLACE FUNCTION postfix_relocated_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_destination -AS $$ - DECLARE - record recipient_destination; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT recipient, destination - FROM relocated - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from _sender_ address (MAIL FROM) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: SASL _login_ names that own _sender_ addresses (MAIL FROM): --- set of sender_login records. --- --- -CREATE OR REPLACE FUNCTION postfix_smtpd_sender_login_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF sender_login -AS $$ - DECLARE - rec sender_login; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - sender varchar(320) := localpart || '@' || the_domain; - BEGIN - -- Get all addresses for 'localpart' in the primary and aliased domains - FOR rec IN - SELECT sender, local_part || '@' || domainname - FROM domain_name, users - WHERE domain_name.gid = did - AND users.gid = did - AND users.local_part = localpart - LOOP - RETURN NEXT rec; - END LOOP; - IF NOT FOUND THEN - -- Loop over the alias addresses for localpart@the_domain - FOR rec IN - SELECT DISTINCT sender, destination - FROM alias - WHERE alias.gid = did - AND alias.address = localpart - LOOP - RETURN NEXT rec; - END LOOP; - END IF; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_transport records --- --- -CREATE OR REPLACE FUNCTION postfix_transport_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_transport -AS $$ - DECLARE - record recipient_transport; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname = the_domain); - transport_id bigint; - BEGIN - IF did IS NULL THEN - RETURN; - END IF; - - SELECT tid INTO transport_id - FROM users - WHERE gid = did AND local_part = localpart; - - IF transport_id IS NULL THEN - SELECT tid INTO STRICT transport_id - FROM domain_data - WHERE gid = did; - END IF; - - FOR record IN - SELECT recipient, transport - FROM transport - WHERE tid = transport_id - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_destination records --- --- -CREATE OR REPLACE FUNCTION _interpolate_destination( - IN destination varchar, localpart varchar, IN the_domain varchar) - RETURNS varchar -AS $$ - DECLARE - result varchar(320); - BEGIN - IF position('%' in destination) = 0 THEN - RETURN destination; - END IF; - result := replace(destination, '%n', localpart); - result := replace(result, '%d', the_domain); - result := replace(result, '%=', localpart || '=' || the_domain); - RETURN result; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; - -CREATE OR REPLACE FUNCTION postfix_virtual_alias_map( - IN localpart varchar, IN the_domain varchar) - RETURNS SETOF recipient_destination -AS $$ - DECLARE - recordc recipient_destination; - record recipient_destination; - catchall_cursor refcursor; - recipient varchar(320) := localpart || '@' || the_domain; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - BEGIN - FOR record IN - SELECT recipient, - _interpolate_destination(destination, localpart, the_domain) - FROM alias - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - - IF NOT FOUND THEN - -- There is no matching virtual_alias. If there are no catchall - -- records for this domain, we can just return NULL since Postfix - -- will then later consult mailboxes/relocated itself. But if - -- there is a catchall destination, then it would take precedence - -- over mailboxes/relocated, which is not what we want. Therefore, - -- we must first find out if the query is for an existing mailbox - -- or relocated entry and return the identity mapping if that is - -- the case - OPEN catchall_cursor FOR - SELECT recipient, - _interpolate_destination(destination, localpart, the_domain) - FROM catchall - WHERE gid = did; - FETCH NEXT FROM catchall_cursor INTO recordc; - - IF recordc IS NOT NULL THEN - -- Since there are catchall records for this domain - -- check the mailbox and relocated records and return identity - -- if a matching record exists. - FOR record IN - SELECT recipient, recipient as destination - FROM users - WHERE gid = did - AND local_part = localpart - UNION SELECT recipient, recipient as destination - FROM relocated - WHERE gid = did - AND address = localpart - LOOP - RETURN NEXT record; - END LOOP; - - IF NOT FOUND THEN - -- There were no records found for mailboxes/relocated, - -- so now we can actually iterate the cursor and populate - -- the return set - LOOP - RETURN NEXT recordc; - FETCH NEXT FROM catchall_cursor INTO recordc; - EXIT WHEN recordc IS NULL; - END LOOP; - END IF; - END IF; - CLOSE catchall_cursor; - END IF; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: address_maildir records --- --- -CREATE OR REPLACE FUNCTION postfix_virtual_mailbox_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF address_maildir -AS $$ - DECLARE - rec address_maildir; - did bigint := (SELECT gid FROM domain_name WHERE domainname=the_domain); - address varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR rec IN - SELECT address, domaindir||'/'||users.uid||'/'||directory||'/' - FROM domain_data, users, maillocation - WHERE domain_data.gid = did - AND users.gid = did - AND users.local_part = localpart - AND maillocation.mid = users.mid - LOOP - RETURN NEXT rec; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; --- --- --- Parameters (from recipients address (MAIL TO) [localpart@the_domain]): --- varchar localpart --- varchar the_domain --- Returns: recipient_uid records --- --- -CREATE OR REPLACE FUNCTION postfix_virtual_uid_map( - IN localpart varchar, IN the_domain varchar) RETURNS SETOF recipient_uid -AS $$ - DECLARE - record recipient_uid; - recipient varchar(320) := localpart || '@' || the_domain; - BEGIN - FOR record IN - SELECT recipient, uid - FROM users - WHERE gid = (SELECT gid - FROM domain_name - WHERE domainname = the_domain) - AND local_part = localpart - LOOP - RETURN NEXT record; - END LOOP; - RETURN; - END; -$$ LANGUAGE plpgsql STABLE -RETURNS NULL ON NULL INPUT -EXTERNAL SECURITY INVOKER; diff -r 659c4476c57c -r b678a1c43027 po/de.po --- a/po/de.po Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1926 +0,0 @@ -# German translations for vmm package. -# Copyright (C) 2009 Free Software Foundation, Inc. -# This file is distributed under the same license as the vmm package. -# Pascal Volk <p.volk@veb-it.de>, 2009. -# Mario Blättermann <mario.blaettermann@gmail.com>, 2011, 2014. -# -msgid "" -msgstr "" -"Project-Id-Version: vmm 0.6.3-pre1\n" -"Report-Msgid-Bugs-To: user+vmm/tp@localhost.localdomain.org\n" -"POT-Creation-Date: 2014-03-23 20:10+0000\n" -"PO-Revision-Date: 2014-03-24 18:14+0100\n" -"Last-Translator: Mario Blättermann <mario.blaettermann@gmail.com>\n" -"Language-Team: German <translation-team-de@lists.sourceforge.net>\n" -"Language: de\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 1.5.4\n" - -#. TP: Hm, what “quotation marks” should be used? -#. If you are unsure have a look at: -#. http://en.wikipedia.org/wiki/Quotation_mark,_non-English_usage -#: VirtualMailManager/account.py:60 VirtualMailManager/alias.py:35 -#: VirtualMailManager/catchall.py:44 VirtualMailManager/domain.py:131 -#: VirtualMailManager/relocated.py:39 -#, python-format -msgid "The domain '%s' does not exist." -msgstr "Die Domain »%s« existiert nicht." - -#: VirtualMailManager/account.py:123 -#, python-format -msgid "The mailbox format '%(mbfmt)s' requires Dovecot >= v%(version)s." -msgstr "Das Postfachformat »%(mbfmt)s« benötigt Dovecot >= v%(version)s." - -#: VirtualMailManager/account.py:166 VirtualMailManager/cli/handler.py:93 -#: VirtualMailManager/handler.py:683 VirtualMailManager/handler.py:789 -#: VirtualMailManager/handler.py:815 VirtualMailManager/handler.py:823 -#: VirtualMailManager/handler.py:831 VirtualMailManager/handler.py:839 -#: VirtualMailManager/handler.py:858 VirtualMailManager/handler.py:870 -#, python-format -msgid "The account '%s' does not exist." -msgstr "Das Konto »%s« existiert nicht." - -#: VirtualMailManager/account.py:222 VirtualMailManager/account.py:243 -#: VirtualMailManager/cli/handler.py:77 VirtualMailManager/handler.py:651 -#, python-format -msgid "The account '%s' already exists." -msgstr "Das Konto »%s« existiert bereits." - -#: VirtualMailManager/account.py:225 VirtualMailManager/handler.py:811 -#, python-format -msgid "Could not accept password: '%s'" -msgstr "Passwort konnte nicht akzeptiert werden: »%s«" - -#: VirtualMailManager/account.py:246 -#, python-format -msgid "No password set for account: '%s'" -msgstr "Kein Passwort festgelegt für Konto: »%s«" - -#: VirtualMailManager/account.py:285 -#, python-format -msgid "Unknown field: '%s'" -msgstr "Unbekanntes Feld: »%s«" - -#: VirtualMailManager/account.py:307 VirtualMailManager/domain.py:331 -msgid "PostgreSQL-based dictionary quota requires Dovecot >= v1.1.2." -msgstr "PostgreSQL-basierte Kontingentbeschränkung benötigt Dovecot >= v1.1.2." - -#. TP: A service (e.g. pop3 or imap) may be enabled/usable or -#. disabled/unusable for a user. -#: VirtualMailManager/account.py:370 -msgid "disabled" -msgstr "deaktiviert" - -#: VirtualMailManager/account.py:370 -msgid "enabled" -msgstr "aktiviert" - -#: VirtualMailManager/account.py:409 -#, python-format -msgid "Could not fetch information for account: '%s'" -msgstr "Informationen zum Konto konnten nicht geholt werden: »%s«" - -#: VirtualMailManager/account.py:453 -#, python-format -msgid "There are %(count)d aliases with the destination address '%(address)s'." -msgstr "Es gibt %(count)d Alias(e) mit der Zieladresse »%(address)s«." - -#: VirtualMailManager/account.py:482 -msgid "UID must be an int/long." -msgstr "Die UID muss eine Ganzzahl sein." - -#: VirtualMailManager/account.py:484 -msgid "UID must be greater than 0." -msgstr "Die UID muss größer als 0 sein." - -#: VirtualMailManager/account.py:493 -#, python-format -msgid "There is no account with the UID: '%d'" -msgstr "Es existiert kein Konto mit der UID »%d«." - -#: VirtualMailManager/alias.py:61 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"Currently this alias expands into %(count)i/%(limit)i recipients.\n" -"%(count_new)i additional destination(s) will render this alias unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit" -msgstr "" -"%(count_new)i neu(e) Ziel(e) konnten nicht zum Alias »%(address)s«\n" -"hinzugefügt werden. Gegenwärtig gilt dieser Alias für %(count)i/%(limit)i\n" -"Empfänger. Durch Hinzufügen von %(count_new)i Ziel(en) wird dieser Alias\n" -"unbenutzbar.\n" -"Hinweis: Erhöhen Sie den Wert für »virtual_alias_expansion_limit« in Postfix." - -#: VirtualMailManager/alias.py:68 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"This alias already exceeds its expansion limit (%(count)i/%(limit)i).\n" -"So its unusable, all messages addressed to this alias will be bounced.\n" -"Hint: Delete some destination addresses." -msgstr "" -"%(count_new)i neu(e) Ziel(e) konnten nicht zu Alias »%(address)s«\n" -"hinzugefügt werden. Dieser Alias übersteigt bereits die Begrenzung\n" -"auf (%(count)i/%(limit)i). Daher wird er unbenutzbar, und alle an\n" -"diesen Alias adressierten Nachrichten werden zurückgehalten.\n" -"Hinweis: Löschen Sie einige Zieladressen." - -#: VirtualMailManager/alias.py:155 VirtualMailManager/alias.py:172 -#: VirtualMailManager/alias.py:179 VirtualMailManager/handler.py:712 -#, python-format -msgid "The alias '%s' does not exist." -msgstr "Der Alias »%s« existiert nicht." - -#: VirtualMailManager/alias.py:163 -#, python-format -msgid "No suitable destinations left to remove from alias '%s'." -msgstr "Aus dem Alias »%s« können keine weiteren Ziele mehr entfernt werden." - -#: VirtualMailManager/aliasdomain.py:50 -#, python-format -msgid "The domain '%s' is a primary domain." -msgstr "Die Domain »%s« ist eine primäre Domain." - -#: VirtualMailManager/aliasdomain.py:69 -#, python-format -msgid "The alias domain '%s' already exists." -msgstr "Die Alias-Domain »%s« existiert bereits." - -#: VirtualMailManager/aliasdomain.py:72 VirtualMailManager/aliasdomain.py:106 -msgid "No destination domain set for the alias domain." -msgstr "Keine Ziel-Domain für die Alias-Domain angegeben." - -#: VirtualMailManager/aliasdomain.py:75 VirtualMailManager/aliasdomain.py:109 -#, python-format -msgid "The target domain '%s' does not exist." -msgstr "Die Ziel-Domain »%s« existiert nicht." - -#: VirtualMailManager/aliasdomain.py:88 VirtualMailManager/aliasdomain.py:112 -#: VirtualMailManager/aliasdomain.py:133 -#, python-format -msgid "The alias domain '%s' does not exist." -msgstr "Die Alias-Domain »%s« existiert nicht." - -#: VirtualMailManager/aliasdomain.py:98 -#, python-format -msgid "There is no primary domain for the alias domain '%s'." -msgstr "Es gibt keine primäre Domain für die Alias-Domain »%s«." - -#: VirtualMailManager/aliasdomain.py:115 -#, python-format -msgid "The alias domain '%(alias)s' is already assigned to the domain '%(domain)s'." -msgstr "Die Alias-Domain »%(alias)s« ist bereits der Domain »%(domain)s« zugeordnet." - -#: VirtualMailManager/catchall.py:69 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to catch-all alias for\n" -"domain '%(domain)s'. Currently this alias expands into %(count)i/%(limit)i\n" -"recipients. %(count_new)i additional destination(s) will render this alias\n" -"unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit" -msgstr "" -"%(count_new)i neu(e) Ziel(e) konnten nicht zum Catch-All-Alias für die\n" -"Domain »%(domain)s« hinzugefügt werden. Gegenwärtig gilt dieser Alias für\n" -"%(count)i/%(limit)i Empfänger. Durch Hinzufügen von %(count_new)i Ziel(en)\n" -"wird dieser Alias unbenutzbar.\n" -"Hinweis: Erhöhen Sie den Wert für »virtual_alias_expansion_limit« in Postfix." - -#: VirtualMailManager/catchall.py:77 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to catch-all alias for domain\n" -"'%(domain)s'. This alias already exceeds its expansion limit (%(count)i/%(limit)i).\n" -"So its unusable, all messages addressed to this alias will be bounced.\n" -"Hint: Delete some destination addresses." -msgstr "" -"%(count_new)i neu(e) Ziel(e) konnten nicht zum Catch-All-Alias für die\n" -"Domain »%(domain)s« hinzugefügt werden. Dieser Alias übersteigt bereits\n" -"die Begrenzung auf (%(count)i/%(limit)i). Daher wird er unbenutzbar, und\n" -"alle an diesen Alias adressierten Nachrichten werden zurückgehalten.\n" -"Hinweis: Löschen Sie einige Zieladressen." - -#: VirtualMailManager/catchall.py:151 VirtualMailManager/catchall.py:169 -#: VirtualMailManager/catchall.py:176 -#, python-format -msgid "There are no catch-all aliases defined for domain '%s'." -msgstr "Für die Domain »%s« sind keine Catch-All-Aliase definiert." - -#: VirtualMailManager/catchall.py:159 -#, python-format -msgid "No suitable destinations left to remove from the catch-all alias of domain '%s'." -msgstr "Für die Entfernung aus dem Catch-All-Alias für die Domain »%s« sind keine Ziele mehr verfügbar." - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:78 -msgid "Enter new password: " -msgstr "Neues Passwort eingeben: " - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:80 -msgid "Retype new password: " -msgstr "Neues Passwort wiederholen: " - -#: VirtualMailManager/cli/__init__.py:85 VirtualMailManager/cli/config.py:53 -msgid "Too many failures - try again later." -msgstr "Zu viele Fehlschläge – versuchen Sie es später erneut." - -#: VirtualMailManager/cli/__init__.py:91 -msgid "Sorry, passwords do not match." -msgstr "Entschuldigung, die Passwörter stimmen nicht überein." - -#: VirtualMailManager/cli/__init__.py:95 -msgid "Sorry, empty passwords are not permitted." -msgstr "Entschuldigung, leere Passwörter sind nicht zulässig." - -#. TP: There are some words enclosed within angle brackets '<'word'>'. They -#. are used to indicate replaceable arguments. Please do not translate them. -#. -#. The descriptions of subcommands may contain the both keywords 'domain' -#. and 'force', enclosed within single quotes. Please keep them as they are. -#. -#. TP: description of subcommand configget -#: VirtualMailManager/cli/clihelp.py:21 -msgid "" -"This subcommand is used to display the actual value\n" -"of the given configuration <option>." -msgstr "" -"Dieser Unterbefehl wird dazu verwendet, den derzeitigen\n" -"Wert der angegebenen Konfigurationsoption <option> anzuzeigen." - -#. TP: description of subcommand configset -#: VirtualMailManager/cli/clihelp.py:24 -msgid "" -"Use this subcommand to set or update a single\n" -"configuration option's value. <option> is the configuration option, <value>\n" -"is the <option>'s new value." -msgstr "" -"Verwenden Sie diesen Unterbefehl, um den Wert einer\n" -"einzelnen Konfigurationsoption festzulegen oder zu\n" -"aktualisieren. <option> ist die Konfigurationsoption,\n" -"<value> ist der neue Wert der Option." - -#: VirtualMailManager/cli/clihelp.py:27 VirtualMailManager/cli/clihelp.py:42 -msgid "" -"Note: This subcommand will create a new vmm.cfg without any comments.\n" -"Your current configuration file will be backed as vmm.cfg.bak." -msgstr "" -"Hinweis: Dieser Unterbefehl erzeugt eine neue vmm.cfg ohne\n" -"jegliche Kommentare. Ihre derzeitige Konfigurationsdatei\n" -"wird als vmm.cfg.bak gesichert." - -#. TP: description of subcommand configure -#: VirtualMailManager/cli/clihelp.py:30 -msgid "" -"Starts the interactive configuration for all\n" -"configuration sections." -msgstr "" -"Startet den interaktiven Konfigurationsmodus für\n" -"alle Konfigurationsabschnitte." - -#: VirtualMailManager/cli/clihelp.py:32 -msgid "" -"In this process the currently set value of each option will be displayed\n" -"in square brackets. If no value is configured, the default value of each\n" -"option will be displayed in square brackets. Press the return key, to accept\n" -"the displayed value." -msgstr "" -"In diesem Prozess wird der gegenwärtig für jede Option gesetzte Wert\n" -"in eckigen Klammern angezeigt. Falls kein Wert eingestellt ist, wird\n" -"der Vorgabewert jeder Option in eckigen Klammern angezeigt. Drücken Sie\n" -"die Eingabetaste, um die angezeigten Werte zu übernehmen." - -#: VirtualMailManager/cli/clihelp.py:36 -msgid "" -"If the optional argument <section> is given, only the configuration\n" -"options from the given section will be displayed and will be configurable.\n" -"The following sections are available:\n" -msgstr "" -"Falls das optionale Argument <section> angegeben wird, dann werden\n" -"nur die Konfigurationsoptionen aus dem entsprechenden Abschnitt\n" -"angezeigt und konfigurierbar sein. Die folgenden Abschnitte sind\n" -"verfügbar:\n" - -#: VirtualMailManager/cli/clihelp.py:41 -msgid "All configuration options are described in vmm.cfg(5)." -msgstr "Alle Konfigurationsoptionen sind in vmm.cfg(5) beschrieben." - -#. TP: description of subcommand getuser -#: VirtualMailManager/cli/clihelp.py:45 -msgid "" -"If only the <uid> is available, for example from process\n" -"list, the subcommand getuser will show the user's address." -msgstr "" -"Falls nur die <uid> verfügbar ist, zum Beispiel aus der Prozess-\n" -"liste, zeigt der Unterbefehl getuser die Adresse des Benutzers an." - -#. TP: description of subcommand listaddresses -#: VirtualMailManager/cli/clihelp.py:48 -msgid "" -"This command lists all defined addresses.\n" -"Addresses belonging to alias-domains are prefixed with a '-', addresses of\n" -"regular domains with a '+'. Additionally, the letters 'u', 'a', and 'r'\n" -"indicate the type of each address: user, alias and relocated respectively.\n" -"The output can be limited with an optional <pattern>." -msgstr "" -"Dieser Befehl listet alle definierten Adressen auf. Adressen, die zu\n" -"Alias-Domains gehören, erhalten das Präfix »-«, Adressen regulärer\n" -"Domains das Präfix »+«. Zusätzlich geben die Buchstaben »u«, »a« und\n" -"»r« den Typ jeder Adresse an: »user«, »alias« bzw. »relocated«. Die\n" -"Ausgabe kann durch ein optionales Muster <pattern> begrenzt werden." - -#: VirtualMailManager/cli/clihelp.py:53 VirtualMailManager/cli/clihelp.py:60 -#: VirtualMailManager/cli/clihelp.py:67 VirtualMailManager/cli/clihelp.py:82 -#: VirtualMailManager/cli/clihelp.py:88 -#, no-python-format -msgid "" -"To perform a wild card search, the % character can be used at the start\n" -"and/or the end of the <pattern>." -msgstr "" -"Um eine Suche mit Platzhaltern auszuführen, kann das %-Zeichen am Anfang\n" -"und/oder am Ende des Musters <pattern> verwendet werden." - -#. TP: description of subcommand listaliases -#: VirtualMailManager/cli/clihelp.py:56 -msgid "" -"This command lists all defined aliases. Aliases\n" -"belonging to alias-domains are prefixed with a '-', addresses of regular\n" -"domains with a '+'. The output can be limited with an optional <pattern>." -msgstr "" -"Dieser Befehl listet alle definierten Aliase auf. Aliase, die zu\n" -"Alias-Domains gehören, erhalten das Präfix »-«, Adressen regulärer\n" -"Domains das Präfix »+«. Die Ausgabe kann durch ein optionales\n" -"Muster <pattern> begrenzt werden." - -#. TP: description of subcommand listdomains -#: VirtualMailManager/cli/clihelp.py:63 -msgid "" -"This subcommand lists all available domains. All\n" -"domain names will be prefixed either with `[+]', if the domain is a primary\n" -"domain, or with `[-]', if it is an alias domain name. The output can be\n" -"limited with an optional <pattern>." -msgstr "" -"Dieser Unterbefehl listet alle verfügbaren Domains auf.\n" -"Allen Domainnamen wird entweder das Präfix [+] vorangestellt,\n" -"wenn die Domain eine primäre Domain ist, oder ein [-], falls\n" -"es ein Alias-Domainname ist. Die Ausgabe kann durch ein optionales\n" -"Muster <pattern> begrenzt werden." - -#. TP: description of subcommand listpwschemes -#: VirtualMailManager/cli/clihelp.py:70 -msgid "" -"This subcommand lists all password schemes which\n" -"could be used in the vmm.cfg as value of the misc.password_scheme option.\n" -"The output varies, depending on the used Dovecot version and the system's\n" -"libc." -msgstr "" -"Dieser Unterbefehl listet alle Passwortschemata auf, die\n" -"in vmm.cfg als Wert für die Option misc.password_scheme\n" -"verwendet werden können. Die Ausgabe ist von der verwendeten\n" -"Dovecot-Version und der im System installierten libc abhängig." - -#: VirtualMailManager/cli/clihelp.py:74 -msgid "" -"When your Dovecot installation isn't too old, you will see additionally\n" -"a few usable encoding suffixes. One of them can be appended to the password\n" -"scheme." -msgstr "" -"Sofern Ihre Dovecot-Installation nicht zu alt ist, sehen Sie\n" -"zusätzlich einige verwendbare Kodierungs-Suffixe. Eines davon\n" -"kann an das Passwort-Schema angehängt werden." - -#. TP: description of subcommand listrelocated -#: VirtualMailManager/cli/clihelp.py:78 -msgid "" -"This command lists all defined relocated addresses.\n" -"Relocated entries belonging to alias-domains are prefixed with a '-', addresses\n" -"of regular domains with a '+'. The output can be limited with an optional\n" -"<pattern>." -msgstr "" -"Dieser Unterbefehl listet alle definierten Umzugs-Adressen auf.\n" -"Allen Domainnamen wird entweder das Präfix [+] vorangestellt,\n" -"wenn die Domain eine primäre Domain ist, oder ein [-], falls\n" -"es ein Alias-Domainname ist. Die Ausgabe kann durch ein optionales\n" -"Muster <pattern> begrenzt werden." - -#. TP: description of subcommand listusers -#: VirtualMailManager/cli/clihelp.py:85 -msgid "" -"This command lists all user accounts. User accounts\n" -"belonging to alias-domains are prefixed with a '-', addresses of regular\n" -"domains with a '+'. The output can be limited with an optional <pattern>." -msgstr "" -"Dieser Unterbefehl listet alle Benutzerkonten auf.\n" -"Allen Domainnamen wird entweder das Präfix [+] vorangestellt,\n" -"wenn die Domain eine primäre Domain ist, oder ein [-], falls\n" -"es ein Alias-Domainname ist. Die Ausgabe kann durch ein optionales\n" -"Muster <pattern> begrenzt werden." - -#. TP: description of subcommand version -#: VirtualMailManager/cli/clihelp.py:91 -msgid "" -"Prints vmm's version and copyright information to stdout.\n" -"After this vmm exits." -msgstr "" -"Gibt die Version von vmm und die Copyright-Informationen\n" -"in die Standardausgabe aus, danach wird vmm beendet." - -#. TP: description of subcommand domainadd -#: VirtualMailManager/cli/clihelp.py:94 -msgid "" -"Adds the new domain into the database and creates the\n" -"domain directory." -msgstr "" -"Fügt die neue Domain zur Datenbank hinzu und erstellt\n" -"das Domain-Verzeichnis." - -#: VirtualMailManager/cli/clihelp.py:96 -msgid "" -"If the optional argument <transport> is given, it will override the\n" -"default transport (domain.transport) from vmm.cfg. The specified <transport>\n" -"will be the default transport for all new accounts in this domain." -msgstr "" -"Falls das optionale Argument <transport> angegeben ist, wird dadurch der\n" -"in vmm.cfg (domain.transport) angegebene Transport außer Kraft gesetzt. Der\n" -"angegebene <transport> wird dadurch der Vorgabe-Transport für alle\n" -"neuen Konten in dieser Domain." - -#: VirtualMailManager/cli/clihelp.py:99 -msgid "Configuration-related behavior:" -msgstr "Konfigurationsbezogenes Verhalten:" - -#: VirtualMailManager/cli/clihelp.py:101 -msgid "" -"When that option is set to true (default) vmm will automatically create\n" -"the postmaster account for the new domain and prompt for postmaster@<fqdn>'s\n" -"password." -msgstr "" -"Wenn der Wert dieser Option auf »true« gesetzt ist (Vorgabe), erstellt\n" -"vmm das Postmaster-Konto für die neue Domain und erfragt das\n" -"Passwort für postmaster@<fqdn>." - -#: VirtualMailManager/cli/clihelp.py:105 -msgid "" -"When the value of that option is also set to true, vmm will automatically\n" -"create the postmaster account for the new domain and print the generated\n" -"postmaster password to stdout." -msgstr "" -"Wenn der Wert dieser Option auch auf »true« gesetzt ist, erstellt vmm\n" -"automatisch das Postmaster-Konto für die neue Domain und gibt das\n" -"generierte Passwort in die Standardausgabe aus." - -#. TP: description of subcommand domaindelete -#: VirtualMailManager/cli/clihelp.py:109 -msgid "" -"This subcommand deletes the domain specified by\n" -"<fqdn>." -msgstr "" -"Dieser Unterbefehl löscht die durch <fqdn>\n" -"angegebene Domain." - -#: VirtualMailManager/cli/clihelp.py:111 -msgid "" -"If there are accounts, aliases and/or relocated users assigned to the\n" -"given domain, vmm will abort the requested operation and show an error\n" -"message. If you know, what you are doing, you can specify the optional keyword\n" -"'force'." -msgstr "" -"Falls der angegebenen Domain Konten, Aliase oder umgezogene Benutzer\n" -"zugeordnet sind, bricht vmm den angeforderten Vorgang ab und zeigt eine\n" -"Fehlermeldung an. Falls Sie genau wissen, was Sie tun, können Sie das\n" -"spezielle Schlüsselwort »force« angeben." - -#: VirtualMailManager/cli/clihelp.py:115 -msgid "" -"If you really always know what you are doing, edit your vmm.cfg and set\n" -"the option domain.force_deletion to true." -msgstr "" -"Wenn Sie wirklich wissen, was Sie tun, bearbeiten Sie Ihre vmm.cfg\n" -"und setzen Sie die Option domain.force_deletion auf »true«." - -#. TP: description of subcommand domaininfo -#: VirtualMailManager/cli/clihelp.py:118 -msgid "" -"This subcommand shows some information about the\n" -"given domain." -msgstr "" -"Dieser Unterbefehl zeigt Informationen über die\n" -"angegebene Domain an." - -#: VirtualMailManager/cli/clihelp.py:120 -msgid "" -"For a more detailed information about the domain the optional argument\n" -"<details> can be specified. A possible <details> value can be one of the\n" -"following six keywords:" -msgstr "" -"Für detailliertere Informationen zur Domain kann optional das Argument\n" -"<details> angegeben werden. Mögliche Werte für <details> sind die\n" -"folgenden sechs Schlüsselwörter:" - -#. TP: description of subcommand domainquota -#: VirtualMailManager/cli/clihelp.py:125 -msgid "" -"This subcommand is used to configure a new quota\n" -"limit for the accounts of the domain - not for the domain itself." -msgstr "" -"Dieser Unterbefehl wird dazu verwendet, die neue Kontingent-\n" -"Begrenzung für die Konten der Domain festzulegen – nicht für\n" -"die Domain selbst." - -#: VirtualMailManager/cli/clihelp.py:127 -msgid "" -"The default quota limit for accounts is defined in the vmm.cfg\n" -"(domain.quota_bytes and domain.quota_messages)." -msgstr "" -"Die vorgegebene Kontingentbegrenzung für Konten ist in der\n" -"vmm.cfg festgelegt (domain.quota_bytes und domain.quota_messages)." - -#: VirtualMailManager/cli/clihelp.py:129 -msgid "" -"The new quota limit will affect only those accounts for which the limit\n" -"has not been overridden. If you want to restore the default to all accounts,\n" -"you may pass the keyword 'force'. When the argument <messages> was omitted the\n" -"default number of messages 0 (zero) will be applied." -msgstr "" -"Die neue Kontingentbegrenzung wirkt sich nur auf Konten aus, für die die\n" -"Kontingentbegrenzung nicht außer Kraft gesetzt wurde. Falls Sie die Vorgabe\n" -"für alle Konten wiederherstellen wollen, können Sie das Schlüsselwort\n" -"»force« angeben. Falls das Argument <messages> fehlt, wird die vorgegebene\n" -"Nachrichtenanzahl 0 (null) verwendet." - -#. TP: description of subcommand domainservices -#: VirtualMailManager/cli/clihelp.py:134 -msgid "" -"To define which services could be used by the\n" -"users of the domain — with the given <fqdn> — use this subcommand." -msgstr "" -"Verwenden Sie diesen Unterbefehl, um mit der angegebenen\n" -"<fqdn> festzulegen, welche Dienste von welchen Benutzern\n" -"dieser Domain genutzt werden dürfen." - -#: VirtualMailManager/cli/clihelp.py:136 -msgid "" -"Each specified <service> will be enabled/usable. All other services\n" -"will be deactivated/unusable. Possible <service> names are:" -msgstr "" -"Jeder angegebene <service> wird aktiviert und benutzbar.\n" -"Alle anderen Dienste werden deaktiviert und nicht nutzbar.\n" -"Mögliche Namen für <service> sind:" - -#: VirtualMailManager/cli/clihelp.py:139 -msgid "" -"The new service set will affect only those accounts for which the set has\n" -"not been overridden. If you want to restore the default to all accounts, you\n" -"may pass the keyword 'force'." -msgstr "" -"Die neue Service-Festlegung beeinflusst nur jene Konten, für die die\n" -"Festlegung nicht außer Kraft gesetzt wird. Falls Sie die Vorgabe für\n" -"alle Konten wiederherstellen wollen, können Sie das Schlüsselwort\n" -"»force« übergeben." - -#. TP: description of subcommand domaintransport -#: VirtualMailManager/cli/clihelp.py:143 -msgid "" -"A new transport for the indicated domain can be\n" -"set with this subcommand." -msgstr "" -"Ein neuer Transport für die angegebene Domain\n" -"kann mit diesem Unterbefehl festgelegt werden." - -#: VirtualMailManager/cli/clihelp.py:145 -msgid "" -"The new transport will affect only those accounts for which the transport\n" -"has not been overridden. If you want to restore the default to all accounts,\n" -"you may pass the keyword 'force'." -msgstr "" -"Ein neuer Transport wirkt sich nur auf jene Konten aus, für die der Transport\n" -"nicht außer Kraft gesetzt wurde. Wenn Sie die Vorgabe für alle Konten\n" -"wiederherstellen wollen, können Sie das Schlüsselwort »force« übergeben." - -#. TP: description of subcommand domainnote -#: VirtualMailManager/cli/clihelp.py:149 -msgid "" -"With this subcommand, it is possible to attach a\n" -"note to the specified domain. Without an argument, an existing note is\n" -"removed." -msgstr "" -"Mit diesem Unterbefehl können Sie eine Notiz an die angegebene\n" -"Domain anhängen. Wenn kein Argument angegeben ist, wird eine\n" -"existierende Notiz gelöscht." - -#. TP: description of subcommand aliasdomainadd -#: VirtualMailManager/cli/clihelp.py:153 -msgid "" -"This subcommand adds the new alias domain\n" -"(<fqdn>) to the destination <domain> that should be aliased." -msgstr "" -"Dieser Unterbefehl fügt eine neue Alias-Domain (<fqdn>)\n" -"zur gewünschten Ziel-<domain> hinzu." - -#. TP: description of subcommand aliasdomaindelete -#: VirtualMailManager/cli/clihelp.py:156 -msgid "" -"Use this subcommand if the alias domain\n" -"<fqdn> should be removed." -msgstr "" -"Verwenden Sie diesen Unterbefehl, falls die Alias-\n" -"Domain <fqdn> entfernt werden soll." - -#. TP: description of subcommand aliasdomaininfo -#: VirtualMailManager/cli/clihelp.py:159 -msgid "" -"This subcommand shows to which domain the alias\n" -"domain <fqdn> is assigned to." -msgstr "" -"Dieser Unterbefehl zeigt, welcher Domain die Alias-Domain\n" -"<fqdn> zugeordnet ist." - -#. TP: description of subcommand aliasdomainswitch -#: VirtualMailManager/cli/clihelp.py:162 -msgid "" -"If the destination of the existing alias\n" -"domain <fqdn> should be switched to another <destination> use this\n" -"subcommand." -msgstr "" -"Falls das Ziel der existierenden Alias-Domain <fqdn> in\n" -"ein anderes Ziel (<destination>) geändert werden soll,\n" -"verwenden Sie diesen Unterbefehl." - -#. TP: description of subcommand useradd -#: VirtualMailManager/cli/clihelp.py:166 -msgid "" -"Use this subcommand to create a new e-mail account for\n" -"the given <address>." -msgstr "" -"Verwenden Sie diesen Unterbefehl, um ein neues E-Mail-\n" -"Konto für die angegebene <address> anzulegen." - -#: VirtualMailManager/cli/clihelp.py:168 -msgid "" -"If the <password> is not provided, vmm will prompt for it interactively.\n" -"When no <password> is provided and account.random_password is set to true, vmm\n" -"will generate a random password and print it to stdout after the account has\n" -"been created." -msgstr "" -"Falls <password> nicht angegeben ist, fragt vmm interaktiv danach.\n" -"Wenn kein <password> angegeben ist und account.random_password auf\n" -"»true« gesetzt ist, generiert vmm ein zufälliges Passwort und gibt\n" -"es in die Standardausgabe aus, nachdem das Konto erstellt wurde." - -#. TP: description of subcommand userdelete -#: VirtualMailManager/cli/clihelp.py:173 -msgid "" -"Use this subcommand to delete the account with the\n" -"given <address>." -msgstr "" -"Verwenden Sie diesen Unterbefehl, um das Konto mit der\n" -"angegebenen Adresse <address> zu löschen." - -#: VirtualMailManager/cli/clihelp.py:175 -msgid "" -"If there are one or more aliases with an identical destination address,\n" -"vmm will abort the requested operation and show an error message. To prevent\n" -"this, specify the optional keyword 'force'." -msgstr "" -"Falls ein oder mehrere Aliase mit identischer Zieladresse existieren,\n" -"bricht vmm den angeforderten Vorgang ab und zeigt eine Fehlermeldung an.\n" -"Um dies zu verhindern, geben Sie das optionale Schlüsselwort »force« an." - -#. TP: description of subcommand userinfo -#: VirtualMailManager/cli/clihelp.py:179 -msgid "" -"This subcommand displays some information about the\n" -"account specified by <address>." -msgstr "" -"Dieser Unterbefehl zeigt einige Informationen zu dem mit\n" -"<address> angegebenen Konto an." - -#: VirtualMailManager/cli/clihelp.py:181 -msgid "" -"If the optional argument <details> is given some more information will be\n" -"displayed. Possible values for <details> are:" -msgstr "" -"Wenn das optionale Argument <details> angegeben ist, werden weitere\n" -"Informationen angezeigt. Mögliche Werte für <details> sind:" - -#. TP: description of subcommand username -#: VirtualMailManager/cli/clihelp.py:185 -msgid "" -"The user's real <name> can be set/updated with this\n" -"subcommand." -msgstr "" -"Der echte Name (<name>) dieses Benutzers kann mit diesem\n" -"Unterbefehl festgelegt oder aktualisiert werden." - -#: VirtualMailManager/cli/clihelp.py:187 -msgid "If no <name> is given, the value stored for the account is erased." -msgstr "" -"Falls kein <name> angegebenen ist, wird der für dieses Konto\n" -"gespeicherte Wert gelöscht." - -#. TP: description of subcommand userpassword -#: VirtualMailManager/cli/clihelp.py:190 -msgid "" -"The password of an account can be updated with this\n" -"subcommand." -msgstr "" -"Das Passwort eines Kontos kann mit diesem Unterbefehl\n" -"aktualisiert werden." - -#: VirtualMailManager/cli/clihelp.py:192 -msgid "If no <password> was provided, vmm will prompt for it interactively." -msgstr "Falls kein <password> angegeben wird, bittet vmm interaktiv um die Eingabe des Passworts." - -#. TP: description of subcommand usernote -#: VirtualMailManager/cli/clihelp.py:195 -msgid "" -"With this subcommand, it is possible to attach a note\n" -"to the specified account. Without an argument, an existing note is\n" -"removed." -msgstr "" -"Mit diesem Unterbefehl können Sie eine Notiz an das angegebene\n" -"Konto anhängen. Wenn kein Argument angegeben ist, wird eine\n" -"existierende Notiz gelöscht." - -#. TP: description of subcommand userquota -#: VirtualMailManager/cli/clihelp.py:199 -msgid "" -"This subcommand is used to set a new quota limit for\n" -"the given account." -msgstr "" -"Dieser Unterbefehl wird verwendet, um eine neue Kontingent-\n" -"begrenzung für das angegebene Konto festzulegen." - -#: VirtualMailManager/cli/clihelp.py:201 -msgid "" -"When the argument <messages> was omitted the default number of messages\n" -"0 (zero) will be applied." -msgstr "" -"Wenn das Argument <messages> fehlt, wird die vorgegebene Anzahl\n" -"0 (null) verwendet." - -#: VirtualMailManager/cli/clihelp.py:203 -msgid "" -"Instead of <storage> pass the keyword 'domain' to remove the\n" -"account-specific override, causing the domain's value to be in effect." -msgstr "" -"Anstelle von <storage> übergeben Sie das Schlüsselwort »domain«,\n" -"um die kontenbezogene Außerkraftsetzung zu entfernen, wodurch der Wert\n" -"für die Domain wieder angewendet wird." - -#. TP: description of subcommand userservices -#: VirtualMailManager/cli/clihelp.py:206 -msgid "" -"To grant a user access to the specified services,\n" -"use this command." -msgstr "" -"Verwenden Sie diesen Unterbefehl, um einem Benutzer\n" -"Zugriff auf die angegebenen Dienste zu gewähren." - -#: VirtualMailManager/cli/clihelp.py:208 -msgid "" -"All omitted services will be deactivated/unusable for the user with the\n" -"given <address>." -msgstr "" -"Alle nicht aufgeführten Dienste werden für den Benutzer mit der\n" -"angegebenen Adresse <address> deaktiviert bzw. nicht mehr nutzbar sein." - -#: VirtualMailManager/cli/clihelp.py:210 -msgid "" -"Instead of <service> pass 'domain' to remove the account-specific\n" -"override, causing the domain's value to be in effect." -msgstr "" -"Anstelle von <service> übergeben Sie »domain« um die kontenspezifische\n" -"Außerkraftsetzung zu entfernen, wodurch der für die Domain angegebene\n" -"Wert wirksam wird." - -#. TP: description of subcommand usertransport -#: VirtualMailManager/cli/clihelp.py:213 -msgid "" -"A different <transport> for an account can be\n" -"specified with this subcommand." -msgstr "" -"Mit diesem Unterbefehl geben Sie einen anderen\n" -"<transport> für dieses Konto an." - -#: VirtualMailManager/cli/clihelp.py:215 -msgid "" -"Instead of <transport> pass 'domain' to remove the account-specific\n" -"override, causing the domain's value to be in effect." -msgstr "" -"Anstelle von <transport> übergeben Sie »domain« um die kontenspezifische\n" -"Außerkraftsetzung zu entfernen, wodurch der für die Domain angegebene\n" -"Wert wirksam wird." - -#. TP: description of subcommand aliasadd -#: VirtualMailManager/cli/clihelp.py:218 -msgid "" -"This subcommand is used to create a new alias\n" -"<address> with one or more <destination> addresses." -msgstr "" -"Dieser Unterbefehl wird verwendet, um eine neue Alias-Adresse\n" -"<address> mit einer oder mehrerer Zieladressen <destination>\n" -"einzurichten." - -#: VirtualMailManager/cli/clihelp.py:220 -msgid "" -"Within the destination address, the placeholders '%n', '%d', and '%='\n" -"will be replaced by the local part, the domain, or the email address with '@'\n" -"replaced by '=' respectively. In combination with alias domains, this enables\n" -"domain-specific destinations." -msgstr "" -"Innerhalb der Zieladresse werden die Platzhalter »%n«, »%d« und »%=«\n" -"durch den local-Teil, die Domain oder die E-Mail-Adresse ersetzt, wobei\n" -"dort »@« zu »=« wird. In Kombination mit Alias-Domains werden dadurch\n" -"domainspezifische Ziele aktiviert. " - -#. TP: description of subcommand aliasdelete -#: VirtualMailManager/cli/clihelp.py:225 -msgid "" -"This subcommand is used to delete one or multiple\n" -"<destination>s from the alias with the given <address>." -msgstr "" -"Verwenden Sie diesen Unterbefehl, um eine oder mehrere Ziele\n" -"<destination> aus dem Alias mit der angegebenen <address> zu löschen." - -#: VirtualMailManager/cli/clihelp.py:227 -msgid "" -"When no <destination> address was specified the alias with all its\n" -"destinations will be deleted." -msgstr "" -"Wenn keine Zieladresse mit <destination> angegeben wirde, dann wird der\n" -"Alias mit allen seinen Zielen gelöscht." - -#. TP: description of subcommand aliasinfo -#: VirtualMailManager/cli/clihelp.py:230 -msgid "" -"Information about the alias with the given <address>\n" -"can be displayed with this subcommand." -msgstr "" -"Mit diesem Unterbefehl können Informationen über den Alias\n" -"mit der angegebenen Adresse <address> angezeigt werden." - -#. TP: description of subcommand relocatedadd -#: VirtualMailManager/cli/clihelp.py:233 -msgid "" -"A new relocated user can be created with this\n" -"subcommand." -msgstr "" -"Mit diesem Unterbefehl kann ein neuer umgezogener\n" -"Benutzer angelegt werden." - -#: VirtualMailManager/cli/clihelp.py:235 -msgid "" -"<address> is the user's ex-email address, for example\n" -"b.user@example.com, and <newaddress> points to the new email address where\n" -"the user can be reached." -msgstr "" -"<adress> ist die ehemalige E-Mail-Adresse des Benutzers,\n" -"zum Beispiel be.nutzer@example.com, und <newaddress> bezeichnet\n" -"die neue E-Mail-Adresse, unter der der Benutzer erreichbar ist. " - -#. TP: description of subcommand relocatedinfo -#: VirtualMailManager/cli/clihelp.py:239 -msgid "" -"This subcommand shows the new address of the\n" -"relocated user with the given <address>." -msgstr "" -"Dieser Unterbefehl zeigt die neue Adresse des umgezogenen\n" -"Benutzers mit der angegebenen <address> an." - -#. TP: description of subcommand relocateddelete -#: VirtualMailManager/cli/clihelp.py:242 -msgid "" -"Use this subcommand in order to delete the\n" -"relocated user with the given <address>." -msgstr "" -"Verwenden Sie diesen Unterbefehl, um den umgezogenen\n" -"Benutzer mit der angegebenen <address> zu löschen." - -#. TP: description of subcommand catchalladd -#: VirtualMailManager/cli/clihelp.py:245 -msgid "" -"This subcommand allows to specify destination\n" -"addresses for a domain, which shall receive mail addressed to unknown\n" -"local-parts within that domain. Those catch-all aliases hence \"catch all\" mail\n" -"to any address in the domain (unless a more specific alias, mailbox or\n" -"relocated user exists)." -msgstr "" -"Dieser Unterbefehl ermöglicht die Angabe von Zieladressen für\n" -"eine Domain, die Mails empfangen solle, die an unbekannte\n" -"local-Teile in dieser Domain adressiert sind. Diese Catch-All-Aliase\n" -"fangen so alle Mails an jede Adresse in dieser Domain auf, sofern dafür\n" -"kein spezifischerer Alias, Postfach oder umgezogener Benutzer existiert." - -#: VirtualMailManager/cli/clihelp.py:250 -msgid "" -"WARNING: Catch-all addresses can cause mail server flooding because\n" -"spammers like to deliver mail to all possible combinations of names, e.g.\n" -"to all addresses between abba@example.org and zztop@example.org." -msgstr "" -"WARNUNG: Catch-All-Adressen können den Mailserver mit Spam überfluten, da\n" -"Spammer Mails an alle möglichen Namenskombinationen ausliefern wollen, zum\n" -"Beispiel alle Adressen zwischen abba@example.org und zztop@example.org." - -#. TP: description of subcommand catchallinfo -#: VirtualMailManager/cli/clihelp.py:254 -msgid "" -"This subcommand displays information about catch-all\n" -"aliases defined for the domain <fqdn>." -msgstr "" -"Dieser Unterbefehl zeigt Informationen über Catch-All-\n" -"Aliase an, die für die Domain <fqdn> definiert sind." - -#. TP: description of subcommand catchalldelete -#: VirtualMailManager/cli/clihelp.py:257 -msgid "" -"With this subcommand, catch-all aliases defined\n" -"for a domain can be removed, either all of them, or those <destination>s which\n" -"were specified explicitly." -msgstr "" -"Mit diesem Unterbefehl können die für eine Domain definierten\n" -"Catch-All-Aliase entfernt werden, entweder alle, oder einen, der\n" -"mit <destination> explizit angegeben werden muss." - -#: VirtualMailManager/cli/config.py:32 -#, python-format -msgid "Enter new value for option %(option)s [%(current_value)s]: " -msgstr "Neuer Wert für Option %(option)s [%(current_value)s]: " - -#: VirtualMailManager/cli/config.py:36 -#, python-format -msgid "Using configuration file: %s\n" -msgstr "Konfigurationsdatei wird verwendet: %s\n" - -#: VirtualMailManager/cli/config.py:38 -#, python-format -msgid "* Configuration section: '%s'" -msgstr "* Konfigurationsabschnitt: »%s«" - -#: VirtualMailManager/cli/config.py:50 -#, python-format -msgid "Warning: %s" -msgstr "Warnung: %s" - -#: VirtualMailManager/cli/handler.py:66 -#, python-format -msgid "Invalid section: '%s'" -msgstr "Ungültiger Abschnitt: »%s«" - -#: VirtualMailManager/cli/main.py:32 VirtualMailManager/cli/main.py:67 -#: VirtualMailManager/cli/main.py:70 VirtualMailManager/cli/subcommands.py:756 -#: VirtualMailManager/cli/subcommands.py:776 -#, python-format -msgid "Error: %s" -msgstr "Fehler: %s" - -#: VirtualMailManager/cli/main.py:41 -msgid "You must specify a subcommand at least." -msgstr "Sie müssen mindestens einen Unterbefehl angeben." - -#: VirtualMailManager/cli/main.py:53 -#, python-format -msgid "Unknown subcommand: '%s'" -msgstr "Unbekannter Unterbefehl: »%s«" - -#. TP: We have to cry, because root has killed/interrupted vmm -#. with Ctrl+C or Ctrl+D. -#: VirtualMailManager/cli/main.py:62 -msgid "Ouch!" -msgstr "Autsch!" - -#: VirtualMailManager/cli/main.py:66 VirtualMailManager/cli/main.py:79 -msgid "Warnings:" -msgstr "Warnungen:" - -#: VirtualMailManager/cli/main.py:73 -#, python-format -msgid "Error: Unknown section: '%s'" -msgstr "Fehler: Unbekannter Abschnitt: »%s«" - -#: VirtualMailManager/cli/main.py:76 -#, python-format -msgid "Error: No option '%(option)s' in section: '%(section)s'" -msgstr "Fehler: Keine Option »%(option)s« im Abschnitt: »%(section)s«" - -#: VirtualMailManager/cli/subcommands.py:101 -#, python-format -msgid "Subcommand '%s' is not yet documented." -msgstr "Der Unterbefehl »%s« ist noch nicht dokumentiert." - -#: VirtualMailManager/cli/subcommands.py:108 -#, python-format -msgid "Plan A failed ... trying Plan B: %(subcommand)s %(object)s" -msgstr "Plan A ist gescheitert … Plan B wird versucht: %(subcommand)s %(object)s" - -#: VirtualMailManager/cli/subcommands.py:122 -msgid "Missing alias address and destination." -msgstr "Alias- und Ziel-Adresse fehlen." - -#: VirtualMailManager/cli/subcommands.py:125 -#: VirtualMailManager/cli/subcommands.py:212 -#: VirtualMailManager/cli/subcommands.py:559 -msgid "Missing destination address." -msgstr "Die Ziel-Adresse fehlt." - -#: VirtualMailManager/cli/subcommands.py:132 -#: VirtualMailManager/cli/subcommands.py:142 -msgid "Missing alias address." -msgstr "Die Alias-Adresse fehlt." - -#: VirtualMailManager/cli/subcommands.py:164 -#: VirtualMailManager/cli/subcommands.py:198 -msgid "Missing alias domain name and destination domain name." -msgstr "Domain-Namen für Alias- und Ziel-Domain fehlen." - -#: VirtualMailManager/cli/subcommands.py:167 -#: VirtualMailManager/cli/subcommands.py:201 -msgid "Missing destination domain name." -msgstr "Keine Ziel-Domain angegeben." - -#: VirtualMailManager/cli/subcommands.py:175 -#: VirtualMailManager/cli/subcommands.py:182 -msgid "Missing alias domain name." -msgstr "Keine Alias-Domain angegeben." - -#: VirtualMailManager/cli/subcommands.py:209 -msgid "Missing domain and destination." -msgstr "Domain und Ziel-Adresse fehlen." - -#: VirtualMailManager/cli/subcommands.py:219 -#: VirtualMailManager/cli/subcommands.py:229 -#: VirtualMailManager/cli/subcommands.py:271 -#: VirtualMailManager/cli/subcommands.py:287 -#: VirtualMailManager/cli/subcommands.py:300 -#: VirtualMailManager/cli/subcommands.py:394 -#: VirtualMailManager/cli/subcommands.py:443 -msgid "Missing domain name." -msgstr "Kein Domain-Name angegeben." - -#: VirtualMailManager/cli/subcommands.py:237 -msgid "Missing option name." -msgstr "Kein Optionsname angegeben." - -#: VirtualMailManager/cli/subcommands.py:253 -msgid "Missing option and new value." -msgstr "Option und neuer Wert fehlen." - -#: VirtualMailManager/cli/subcommands.py:255 -msgid "Missing new configuration value." -msgstr "Neuer Konfigurationswert fehlt." - -#: VirtualMailManager/cli/subcommands.py:277 -#, python-format -msgid "Creating account for postmaster@%s" -msgstr "Konto für postmaster@%s wird angelegt" - -#: VirtualMailManager/cli/subcommands.py:293 -#: VirtualMailManager/cli/subcommands.py:307 -#: VirtualMailManager/cli/subcommands.py:385 -#: VirtualMailManager/cli/subcommands.py:406 -#: VirtualMailManager/cli/subcommands.py:435 -#: VirtualMailManager/cli/subcommands.py:615 -#: VirtualMailManager/cli/subcommands.py:628 VirtualMailManager/handler.py:459 -#: VirtualMailManager/handler.py:472 VirtualMailManager/handler.py:487 -#: VirtualMailManager/handler.py:521 VirtualMailManager/handler.py:784 -#, python-format -msgid "Invalid argument: '%s'" -msgstr "Ungültiges Argument: »%s«" - -#: VirtualMailManager/cli/subcommands.py:326 -#: VirtualMailManager/cli/subcommands.py:333 -msgid "Domain" -msgstr "Domain" - -#: VirtualMailManager/cli/subcommands.py:335 -#: VirtualMailManager/cli/subcommands.py:346 -msgid "accounts" -msgstr "Konten" - -#: VirtualMailManager/cli/subcommands.py:337 -#: VirtualMailManager/cli/subcommands.py:345 -#: VirtualMailManager/cli/subcommands.py:1007 -msgid "alias domains" -msgstr "Alias-Domains" - -#: VirtualMailManager/cli/subcommands.py:339 -#: VirtualMailManager/cli/subcommands.py:347 -#: VirtualMailManager/cli/subcommands.py:1077 -msgid "aliases" -msgstr "Aliase" - -#: VirtualMailManager/cli/subcommands.py:341 -#: VirtualMailManager/cli/subcommands.py:348 -#: VirtualMailManager/cli/subcommands.py:1078 -msgid "relocated users" -msgstr "Umgezogene Benutzer" - -#: VirtualMailManager/cli/subcommands.py:343 -#: VirtualMailManager/cli/subcommands.py:349 -msgid "catch-all destinations" -msgstr "Catch-All-Ziele" - -#: VirtualMailManager/cli/subcommands.py:355 -msgid "Missing domain name and storage value." -msgstr "Domain-Name und neuer Speicher-Wert fehlen." - -#: VirtualMailManager/cli/subcommands.py:358 -#: VirtualMailManager/cli/subcommands.py:706 -msgid "Missing storage value." -msgstr "Speicher-Wert fehlt." - -#: VirtualMailManager/cli/subcommands.py:364 -#: VirtualMailManager/cli/subcommands.py:711 -#, python-format -msgid "Invalid storage value: '%s'" -msgstr "Ungültiger Speicher-Wert: »%s«" - -#: VirtualMailManager/cli/subcommands.py:374 -#, python-format -msgid "Neither a valid number of messages nor the keyword 'force': '%s'" -msgstr "Weder eine gültige Nachrichtenanzahl noch das Schlüsselwort »force«: »%s«" - -#: VirtualMailManager/cli/subcommands.py:382 -#: VirtualMailManager/cli/subcommands.py:722 -#, python-format -msgid "Not a valid number of messages: '%s'" -msgstr "Ungültige Nachrichtenanzahl: »%s«" - -#: VirtualMailManager/cli/subcommands.py:417 -#: VirtualMailManager/cli/subcommands.py:736 -#, python-format -msgid "Invalid service arguments: %s" -msgstr "Ungültige Dienst-Argumente: »%s«" - -#: VirtualMailManager/cli/subcommands.py:426 -msgid "Missing domain name and new transport." -msgstr "Domain-Name und neuer Transport fehlen." - -#: VirtualMailManager/cli/subcommands.py:429 -msgid "Missing new transport." -msgstr "Neuer Transport fehlt." - -#: VirtualMailManager/cli/subcommands.py:455 -msgid "Missing UID." -msgstr "Keine UID angegeben." - -#: VirtualMailManager/cli/subcommands.py:456 -#: VirtualMailManager/cli/subcommands.py:653 -#: VirtualMailManager/cli/subcommands.py:661 -msgid "Account" -msgstr "Konto" - -#: VirtualMailManager/cli/subcommands.py:471 -#, python-format -msgid "Unknown help topic: '%s'" -msgstr "Unbekanntes Hilfethema: »%s«" - -#: VirtualMailManager/cli/subcommands.py:484 -msgid "List of available subcommands:" -msgstr "Liste der verfügbaren Unterbefehle:" - -#: VirtualMailManager/cli/subcommands.py:507 -msgid "Usable encoding suffixes:" -msgstr "Verwendbare Encoding-Suffixe:" - -#: VirtualMailManager/cli/subcommands.py:507 -msgid "Usable password schemes:" -msgstr "Verfügbare Passwort-Schemata:" - -#: VirtualMailManager/cli/subcommands.py:557 -msgid "Missing relocated address and destination." -msgstr "Die Adresse des umgezogenen Benutzers und die Ziel-Adresse fehlen." - -#: VirtualMailManager/cli/subcommands.py:566 -#: VirtualMailManager/cli/subcommands.py:573 -msgid "Missing relocated address." -msgstr "Die Adresse des umgezogenen Benutzers fehlt." - -#: VirtualMailManager/cli/subcommands.py:596 -#: VirtualMailManager/cli/subcommands.py:609 -#: VirtualMailManager/cli/subcommands.py:622 -#: VirtualMailManager/cli/subcommands.py:680 -#: VirtualMailManager/cli/subcommands.py:691 -#: VirtualMailManager/cli/subcommands.py:730 -msgid "Missing e-mail address." -msgstr "E-Mail-Adresse fehlt." - -#: VirtualMailManager/cli/subcommands.py:603 -#, python-format -msgid "Generated password: %s" -msgstr "Erzeugtes Passwort: %s" - -#: VirtualMailManager/cli/subcommands.py:662 -msgid "alias addresses" -msgstr "Alias-Adressen" - -#: VirtualMailManager/cli/subcommands.py:668 -msgid "Missing e-mail address and user's name." -msgstr "E-Mail-Adresse und der Name des Benutzers fehlen." - -#: VirtualMailManager/cli/subcommands.py:703 -msgid "Missing e-mail address and storage value." -msgstr "E-Mail-Adresse und Speicher-Wert fehlen." - -#: VirtualMailManager/cli/subcommands.py:744 -msgid "Missing e-mail address and transport." -msgstr "E-Mail-Adresse und Transport fehlen." - -#: VirtualMailManager/cli/subcommands.py:747 -msgid "Missing transport." -msgstr "Transport fehlt." - -#: VirtualMailManager/cli/subcommands.py:757 -msgid "usage: " -msgstr "Aufruf:" - -#. TP: Please adjust translated words like the original text. -#. (It's a table header.) Extract from usage text: -#. usage: vmm subcommand arguments -#. short long -#. subcommand arguments -#. -#. da domainadd fqdn [transport] -#. dd domaindelete fqdn [force] -#: VirtualMailManager/cli/subcommands.py:767 -#, python-format -msgid "" -"usage: %s subcommand arguments\n" -" short long\n" -" subcommand arguments\n" -msgstr "" -"Aufruf: %s Unterbefehl Argumente\n" -" kurz lang\n" -" Unterbefehl Argumente\n" - -#: VirtualMailManager/cli/subcommands.py:786 -msgid "from" -msgstr "vom" - -#. TP: The words 'from', 'version' and 'on' are used in -#. the version information, e.g.: -#. vmm, version 0.5.2 (from 09/09/09) -#. Python 2.5.4 on FreeBSD -#: VirtualMailManager/cli/subcommands.py:786 -msgid "version" -msgstr "Version" - -#: VirtualMailManager/cli/subcommands.py:789 -msgid "on" -msgstr "auf" - -#: VirtualMailManager/cli/subcommands.py:791 -msgid "is free software and comes with ABSOLUTELY NO WARRANTY." -msgstr "ist freie Software und wird OHNE JEGLICHE GARANTIE bereitgestellt." - -#: VirtualMailManager/cli/subcommands.py:800 -msgid "get the address of the user with the given UID" -msgstr "Die Adresse des Benutzers mit der angegebenen UID ermitteln" - -#: VirtualMailManager/cli/subcommands.py:802 -msgid "create a new e-mail user with the given address" -msgstr "Einen neuen E-Mail-Benutzer mit der angegebenen Adresse anlegen" - -#: VirtualMailManager/cli/subcommands.py:804 -msgid "delete the specified user" -msgstr "Den angegebenen Benutzer löschen" - -#: VirtualMailManager/cli/subcommands.py:806 -msgid "display information about the given address" -msgstr "Informationen über die angegebene Adresse anzeigen" - -#: VirtualMailManager/cli/subcommands.py:808 -msgid "set, update or delete the real name for an address" -msgstr "Den echten Namen für eine Adresse festlegen, aktualisieren oder löschen" - -#: VirtualMailManager/cli/subcommands.py:811 -msgid "update the password for the given address" -msgstr "Das Passwort für die angegebene Adresse aktualisieren" - -#: VirtualMailManager/cli/subcommands.py:814 -msgid "update the quota limit for the given address" -msgstr "Die Nutzungsbeschränkung für die angegebene Adresse aktualisieren" - -#: VirtualMailManager/cli/subcommands.py:817 -msgid "enables the specified services and disables all not specified services" -msgstr "Die angegebenen Dienste aktivieren und alle nicht angegebenen Dienste deaktivieren" - -#: VirtualMailManager/cli/subcommands.py:821 -msgid "update the transport of the given address" -msgstr "Den Transport für die angegebene Adresse aktualisieren" - -#: VirtualMailManager/cli/subcommands.py:823 -msgid "set, update or delete the note of the given address" -msgstr "Die Notiz der angegebenen Adresse setzen, aktualisieren oder löschen" - -#: VirtualMailManager/cli/subcommands.py:826 -msgid "create a new alias e-mail address with one or more destinations" -msgstr "Eine neue Alias-E-Mail-Adresse mit einem oder mehreren Zielen anlegen" - -#: VirtualMailManager/cli/subcommands.py:830 -msgid "delete the specified alias e-mail address or one of its destinations" -msgstr "Die angegebene Alias-E-Mail-Adresse oder eines ihrer Ziele löschen" - -#: VirtualMailManager/cli/subcommands.py:833 -msgid "show the destination(s) of the specified alias" -msgstr "Das/die Ziel(e) des angegebenen Alias anzeigen" - -#: VirtualMailManager/cli/subcommands.py:837 -msgid "create a new alias for an existing domain" -msgstr "Einen neuen Alias für eine existierende Domain anlegen" - -#: VirtualMailManager/cli/subcommands.py:839 -msgid "delete the specified alias domain" -msgstr "Die angegebene Alias-Domain löschen" - -#: VirtualMailManager/cli/subcommands.py:841 -msgid "show the destination of the given alias domain" -msgstr "Das Ziel der angegebenen Alias-Domain anzeigen" - -#: VirtualMailManager/cli/subcommands.py:843 -msgid "assign the given alias domain to an other domain" -msgstr "Die angegebene Alias-Domain einer anderen Domain zuordnen" - -#: VirtualMailManager/cli/subcommands.py:848 -msgid "add one or more catch-all destinations for a domain" -msgstr "Ein oder mehrere Catch-All-Zile für eine Domain hinzufügen" - -#: VirtualMailManager/cli/subcommands.py:852 -msgid "delete the specified catch-all destination or all of a domain's destinations" -msgstr "Das angegebene Catch-All-Ziel oder alle Ziele einer Domain löschen" - -#: VirtualMailManager/cli/subcommands.py:855 -msgid "show the catch-all destination(s) of the specified domain" -msgstr "Das/die Catch-All-Ziel(e) der angegebenen Domain anzeigen" - -#: VirtualMailManager/cli/subcommands.py:859 -msgid "create a new domain" -msgstr "Eine neue Domain anlegen" - -#: VirtualMailManager/cli/subcommands.py:861 -msgid "delete the given domain and all its alias domains" -msgstr "Die angegebene Domain und alle ihre Alias-Domains löschen" - -#: VirtualMailManager/cli/subcommands.py:863 -msgid "display information about the given domain" -msgstr "Informationen über die angegebene Domain anzeigen" - -#: VirtualMailManager/cli/subcommands.py:866 -msgid "update the quota limit of the specified domain" -msgstr "Kontingentbeschränkung der angegebenen Domain aktualisieren" - -#: VirtualMailManager/cli/subcommands.py:869 -msgid "enables the specified services and disables all not specified services of the given domain" -msgstr "Aktiviert die angegebenen Dienste und deaktiviert alle nicht angegebenen Dienste der angegebenen Domain" - -#: VirtualMailManager/cli/subcommands.py:873 -msgid "update the transport of the specified domain" -msgstr "Den Transport der angegebenen Domain aktualisieren" - -#: VirtualMailManager/cli/subcommands.py:875 -msgid "set, update or delete the note of the given domain" -msgstr "Die Notiz der angegebenen Domain setzen, aktualisieren oder löschen" - -#: VirtualMailManager/cli/subcommands.py:878 -msgid "list all domains or search for domains by pattern" -msgstr "Alle Domains nach Muster auflisten oder danach suchen" - -#: VirtualMailManager/cli/subcommands.py:880 -msgid "list all addresses or search for addresses by pattern" -msgstr "Alle Adressen nach Muster auflisten oder danach suchen" - -#: VirtualMailManager/cli/subcommands.py:883 -msgid "list all user accounts or search for accounts by pattern" -msgstr "Alle Benutzerkonten anhand des Musters auflisten oder danach suchen" - -#: VirtualMailManager/cli/subcommands.py:886 -msgid "list all aliases or search for aliases by pattern" -msgstr "Alle Aliase anhand des Musters auflisten oder danach suchen" - -#: VirtualMailManager/cli/subcommands.py:888 -msgid "list all relocated users or search for relocated users by pattern" -msgstr "Alle umgezogenen Benutzer anhand des Musters auflisten oder danach suchen" - -#: VirtualMailManager/cli/subcommands.py:893 -msgid "create a new record for a relocated user" -msgstr "Einen neuen Datensatz für einen umgezogenen Benutzer anlegen" - -#: VirtualMailManager/cli/subcommands.py:896 -msgid "delete the record of the relocated user" -msgstr "Den Datensatz eines umgezogenen Benutzers löschen" - -#: VirtualMailManager/cli/subcommands.py:898 -msgid "print information about a relocated user" -msgstr "Informationen über einen umgezogenen Benutzer anzeigen" - -#: VirtualMailManager/cli/subcommands.py:901 -msgid "show the actual value of the configuration option" -msgstr "Den tatsächlichen Wert der Konfigurationsoption anzeigen" - -#: VirtualMailManager/cli/subcommands.py:903 -msgid "set a new value for the configuration option" -msgstr "Einen neuen Wert für die Konfigurationsoption festlegen" - -#: VirtualMailManager/cli/subcommands.py:905 -msgid "start interactive configuration mode" -msgstr "Den interaktiven Konfigurationsmodus starten" - -#: VirtualMailManager/cli/subcommands.py:907 -msgid "lists all usable password schemes and password encoding suffixes" -msgstr "Alle verwendbaren Passwort-Schemata und Encodierungs-Suffixe für Passwörter auflisten" - -#: VirtualMailManager/cli/subcommands.py:910 -msgid "show a help overview or help for the given subcommand" -msgstr "Eine Hilfe-Übersicht oder Hilfe für einen angegebenen Unterbefehl anzeigen" - -#: VirtualMailManager/cli/subcommands.py:912 -msgid "show version and copyright information" -msgstr "Version und urheberrechtliche Informationen anzeigen" - -#. TP: e.g.: [ 0.00%] 21.09 KiB/1.00 GiB -#: VirtualMailManager/cli/subcommands.py:968 -#, python-format -msgid "[%(percent)s%%] %(used)s/%(limit)s" -msgstr "[%(percent)s%%] %(used)s/%(limit)s" - -#. TP: used in e.g. 'Domain information' or 'Account information' -#: VirtualMailManager/cli/subcommands.py:974 -msgid "information" -msgstr "Informationen" - -#: VirtualMailManager/cli/subcommands.py:988 -msgid "Note" -msgstr "Notiz" - -#. TP: used in e.g. 'Existing alias addresses' or 'Existing accounts' -#: VirtualMailManager/cli/subcommands.py:1004 -msgid "Existing" -msgstr "Vorhandene" - -#: VirtualMailManager/cli/subcommands.py:1017 -#: VirtualMailManager/cli/subcommands.py:1069 -#: VirtualMailManager/cli/subcommands.py:1113 -msgid "\tNone" -msgstr "\tKeine" - -#: VirtualMailManager/cli/subcommands.py:1022 -msgid "Alias information" -msgstr "Alias-Informationen" - -#: VirtualMailManager/cli/subcommands.py:1024 -#, python-format -msgid "\tMail for %s will be redirected to:" -msgstr "\tE-Mails für %s werden weitergeleitet an:" - -#: VirtualMailManager/cli/subcommands.py:1031 -msgid "Catch-all information" -msgstr "Catch-All-Information" - -#: VirtualMailManager/cli/subcommands.py:1033 -#, python-format -msgid "\tMail to unknown local-parts in domain %s will be sent to:" -msgstr "\tMails an unbekannte local-Teile in der Domain %s werden gesendet an:" - -#: VirtualMailManager/cli/subcommands.py:1041 -msgid "Relocated information" -msgstr "Verschiebe-Informationen" - -#: VirtualMailManager/cli/subcommands.py:1043 -#, python-format -msgid "\tUser '%(addr)s' has moved to '%(dest)s'" -msgstr "\tDer Benutzer »%(addr)s« ist nach »%(dest)s« umgezogen" - -#: VirtualMailManager/cli/subcommands.py:1058 -msgid "Matching domains" -msgstr "Übereinstimmende Domains" - -#: VirtualMailManager/cli/subcommands.py:1060 -msgid "Existing domains" -msgstr "Existierende Domains" - -#: VirtualMailManager/cli/subcommands.py:1076 -msgid "user accounts" -msgstr "Benutzerkonten" - -#: VirtualMailManager/cli/subcommands.py:1079 -msgid "user accounts and aliases" -msgstr "Benutzerkonten und Aliase" - -#: VirtualMailManager/cli/subcommands.py:1080 -msgid "user accounts and relocated users" -msgstr "Benutzerkonten und umgezogene Benutzer" - -#: VirtualMailManager/cli/subcommands.py:1081 -msgid "aliases and relocated users" -msgstr "Aliase und umgezogene Benutzer" - -#: VirtualMailManager/cli/subcommands.py:1082 -msgid "addresses" -msgstr "Adressen" - -#: VirtualMailManager/cli/subcommands.py:1086 -#, python-format -msgid "Matching %s" -msgstr "Übereinstimmende %s" - -#: VirtualMailManager/cli/subcommands.py:1088 -#, python-format -msgid "Existing %s" -msgstr "Vorhandenes %s" - -#: VirtualMailManager/cli/subcommands.py:1091 -#, python-format -msgid "Invalid address type for list: '%s'" -msgstr "Ungültiger Adresstyp für Liste: »%s«" - -#. TP: the letters 'u', 'a' and 'r' are abbreviations of user, -#. alias and relocated user -#: VirtualMailManager/cli/subcommands.py:1101 -msgid "u" -msgstr "u" - -#: VirtualMailManager/cli/subcommands.py:1102 -msgid "a" -msgstr "a" - -#: VirtualMailManager/cli/subcommands.py:1103 -msgid "r" -msgstr "r" - -#: VirtualMailManager/cli/subcommands.py:1119 -msgid "Alias domain information" -msgstr "Alias-Domain-Informationen" - -#: VirtualMailManager/cli/subcommands.py:1124 -#, python-format -msgid "" -"\tThe alias domain %(alias)s belongs to:\n" -"\t * %(domain)s" -msgstr "" -"\tDie Alias-Domain %(alias)s gehört zu:\n" -"\t * %(domain)s" - -#: VirtualMailManager/common.py:63 -#, python-format -msgid "No such file: '%s'" -msgstr "Datei nicht gefunden: »%s«" - -#: VirtualMailManager/common.py:66 -#, python-format -msgid "File is not executable: '%s'" -msgstr "Datei ist nicht ausführbar: »%s«" - -#: VirtualMailManager/common.py:83 -msgid "GiB" -msgstr "GiB" - -#. TP: abbreviations of gibibyte, tebibyte kibibyte and mebibyte -#: VirtualMailManager/common.py:83 -msgid "TiB" -msgstr "TiB" - -#: VirtualMailManager/common.py:84 -msgid "KiB" -msgstr "KiB" - -#: VirtualMailManager/common.py:84 -msgid "MiB" -msgstr "MiB" - -#. TP: e.g.: '%(size)s %(prefix)s' -> '118.30 MiB' -#: VirtualMailManager/common.py:88 -#, python-format -msgid "%(size)s %(prefix)s" -msgstr "%(size)s %(prefix)s" - -#: VirtualMailManager/common.py:139 -#, python-format -msgid "Invalid transport '%(transport)s' for mailbox format '%(mbfmt)s'." -msgstr "Ungültiger Transport »%(transport)s« für Postfachformat »%(mbfmt)s«." - -#. TP: [domain default] indicates that a user's setting is the same as -#. configured in the user's domain. -#. e.g.: [ 0.84%] 42/5,000 [domain default] -#: VirtualMailManager/common.py:217 -#, python-format -msgid "%s [domain default]" -msgstr "%s [Domain-Vorgabe]" - -#: VirtualMailManager/config.py:89 -#, python-format -msgid "Not a boolean: '%s'" -msgstr "Kein boolescher Wert: »%s«" - -#: VirtualMailManager/config.py:127 -#, python-format -msgid "Bad format: '%s' - expected: section.option" -msgstr "Falsches Format: »%s« - erwartet: Abschnitt.Option" - -#: VirtualMailManager/config.py:378 -#, python-format -msgid "* Section: %s\n" -msgstr "* Abschnitt: %s\n" - -#: VirtualMailManager/config.py:388 VirtualMailManager/config.py:396 -#, python-format -msgid "Check of configuration file %s failed.\n" -msgstr "Überprüfen der Konfigurationsdatei %s ist fehlgeschlagen.\n" - -#: VirtualMailManager/config.py:390 -msgid "Missing options, which have no default value.\n" -msgstr "Optionen fehlen, für die kein Vorgabewert besteht.\n" - -#: VirtualMailManager/config.py:398 VirtualMailManager/config.py:400 -msgid "Invalid configuration values.\n" -msgstr "Ungültige Konfigurationswerte.\n" - -#: VirtualMailManager/config.py:439 VirtualMailManager/config.py:523 -#, python-format -msgid "Not a valid Dovecot version: '%s'" -msgstr "Keine gültige Dovecot-Version: »%s«" - -#: VirtualMailManager/config.py:445 VirtualMailManager/config.py:480 -#, python-format -msgid "Unsupported database module: '%s'" -msgstr "Nicht unterstütztes Datenbankmodul: »%s«" - -#: VirtualMailManager/config.py:450 VirtualMailManager/config.py:488 -#, python-format -msgid "Unknown pgsql SSL mode: '%s'" -msgstr "Unbekannter SSL-Modus für PostgreSQL: »%s«" - -#: VirtualMailManager/config.py:457 VirtualMailManager/config.py:501 -#: VirtualMailManager/maillocation.py:70 -#, python-format -msgid "Unsupported mailbox format: '%s'" -msgstr "Nicht unterstütztes Postfachformat: »%s«" - -#: VirtualMailManager/config.py:473 VirtualMailManager/handler.py:287 -#: VirtualMailManager/handler.py:363 VirtualMailManager/handler.py:368 -#: VirtualMailManager/handler.py:396 -#, python-format -msgid "No such directory: %s" -msgstr "Verzeichnis nicht gefunden: %s" - -#: VirtualMailManager/config.py:512 -#, python-format -msgid "Not a valid size value: '%s'" -msgstr "Ungültiger Größenwert: »%s«" - -#: VirtualMailManager/domain.py:84 -#, python-format -msgid "The domain '%s' is an alias domain." -msgstr "Die Domain »%s« ist eine Alias-Domain." - -#: VirtualMailManager/domain.py:119 -#, python-format -msgid "There are %(account_count)u accounts, %(alias_count)u aliases and %(relocated_count)u relocated users." -msgstr "Es gibt %(account_count)u Konten, %(alias_count)u Aliase und %(relocated_count)u umgezogene Benutzer." - -#: VirtualMailManager/domain.py:134 -#, python-format -msgid "The domain '%s' already exists." -msgstr "Die Domain »%s« existiert bereits." - -#: VirtualMailManager/domain.py:507 -msgid "The domain name is too long" -msgstr "Der Domain-Name ist zu lang." - -#: VirtualMailManager/domain.py:509 -#, python-format -msgid "The domain name '%s' is invalid" -msgstr "Der Domain-Name »%s« ist ungültig" - -#: VirtualMailManager/emailaddress.py:73 -#, python-format -msgid "Missing the '@' sign in address: '%s'" -msgstr "In der Adresse fehlt das @-Zeichen: »%s«" - -#: VirtualMailManager/emailaddress.py:76 -#, python-format -msgid "Too many '@' signs in address: '%s'" -msgstr "Zu viele @-Zeichen in Adresse: »%s«" - -#: VirtualMailManager/emailaddress.py:79 -#, python-format -msgid "Missing local-part in address: '%s'" -msgstr "Fehlender local-Part in Adresse: »%s«" - -#: VirtualMailManager/emailaddress.py:82 -#, python-format -msgid "Missing domain name in address: '%s'" -msgstr "Domain-Name in Adresse fehlt: »%s«" - -#: VirtualMailManager/emailaddress.py:145 -#, python-format -msgid "The local-part '%s' is too long." -msgstr "Der local-Part »%s« ist zu lang." - -#: VirtualMailManager/emailaddress.py:150 -#, python-format -msgid "The local-part '%(l_part)s' contains invalid characters: %(i_chars)s" -msgstr "Der local-Part »%(l_part)s« enthält ungültige Zeichen: %(i_chars)s" - -#: VirtualMailManager/ext/postconf.py:84 -#, python-format -msgid "The value '%s' does not look like a valid Postfix configuration parameter name." -msgstr "Der Wert »%s« sieht nicht wie ein gültiger Konfigurationsparametername für Postfix aus." - -#: VirtualMailManager/handler.py:54 -msgid "an account" -msgstr "ein Konto" - -#: VirtualMailManager/handler.py:55 -msgid "an alias" -msgstr "ein Alias" - -#: VirtualMailManager/handler.py:56 -msgid "a relocated user" -msgstr "ein umgezogener Benutzer" - -#: VirtualMailManager/handler.py:82 -msgid "" -"You are not root.\n" -"\tGood bye!\n" -msgstr "" -"Sie sind kein Administrator.\n" -"\tAuf Wiedersehen.\n" - -#: VirtualMailManager/handler.py:102 -#, python-format -msgid "Could not find '%(cfg_file)s' in: '%(cfg_path)s'" -msgstr "»%(cfg_file)s« konnte nicht in »%(cfg_path)s« gefunden werden" - -#. TP: Please keep the backticks around the command. `chmod 0600 …` -#: VirtualMailManager/handler.py:114 -#, python-format -msgid "" -"wrong permissions for '%(file)s': %(perms)s\n" -"`chmod 0600 %(file)s` would be great." -msgstr "" -"Bitte Zugriffsrechte (%(perms)s) für »%(file)s« anpassen\n" -"»chmod 0600 %(file)s« wäre großartig." - -#: VirtualMailManager/handler.py:134 -#, python-format -msgid "" -"'%(path)s' is not a directory.\n" -"(%(cfg_file)s: section 'misc', option 'base_directory')" -msgstr "" -"»%(path)s« ist kein Verzeichnis.\n" -"(%(cfg_file)s: Abschnitt »misc«, Option »base_directory«)" - -#: VirtualMailManager/handler.py:143 -#, python-format -msgid "" -"\n" -"(%(cfg_file)s: section 'bin', option '%(option)s')" -msgstr "" -"\n" -"(%(cfg_file)s: Abschnitt »bin«, Option »%(option)s«)" - -#: VirtualMailManager/handler.py:157 VirtualMailManager/handler.py:164 -#, python-format -msgid "Unable to import database module '%s'." -msgstr "Datenbankmodul »%s« konnte nicht importiert werden." - -#. TP: %(a_type)s will be one of: 'an account', 'an alias' or -#. 'a relocated user' -#: VirtualMailManager/handler.py:243 -#, python-format -msgid "There is already %(a_type)s with the address '%(address)s'." -msgstr "Es existiert bereits %(a_type)s mit der Adresse »%(address)s«." - -#: VirtualMailManager/handler.py:302 -#, python-format -msgid "'%s' is not a directory." -msgstr "»%s« ist kein Verzeichnis." - -#: VirtualMailManager/handler.py:305 -#, python-format -msgid "The file/directory '%s' already exists." -msgstr "Die Datei oder das Verzeichnis »%s« existiert bereits." - -#: VirtualMailManager/handler.py:335 -msgid "Skipped mailbox folders:" -msgstr "Übersprungene Postfach-Ordner:" - -#: VirtualMailManager/handler.py:355 -#, python-format -msgid "UID '%(uid)u' and/or GID '%(gid)u' are less than %(min_uid)u/%(min_gid)u." -msgstr "UID »%(uid)u« und/oder GID »%(gid)u« sind kleiner als %(min_uid)u/%(min_gid)u." - -#: VirtualMailManager/handler.py:360 VirtualMailManager/handler.py:393 -#, python-format -msgid "Found \"..\" in domain directory path: %s" -msgstr "»..« im Pfad zum Domain-Verzeichnis entdeckt: %s" - -#: VirtualMailManager/handler.py:373 -msgid "Detected owner/group mismatch in home directory." -msgstr "Benutzerverzeichnis gehört dem/der falschen Benutzer/Gruppe." - -#: VirtualMailManager/handler.py:389 -#, python-format -msgid "GID '%(gid)u' is less than '%(min_gid)u'." -msgstr "GID »%(gid)u« ist kleiner als »%(min_gid)u«." - -#: VirtualMailManager/handler.py:400 -#, python-format -msgid "Detected group mismatch in domain directory: %s" -msgstr "Domain-Verzeichnis gehört der falschen Gruppe: %s" - -#: VirtualMailManager/handler.py:476 VirtualMailManager/handler.py:878 -#, python-format -msgid "Unknown service: '%s'" -msgstr "Unbekannter Dienst: »%s«." - -#: VirtualMailManager/handler.py:601 VirtualMailManager/handler.py:625 -#: VirtualMailManager/handler.py:639 -#, python-format -msgid "The pattern '%s' contains invalid characters." -msgstr "Das Muster »%s« enthält ungültige Zeichen." - -#: VirtualMailManager/handler.py:669 VirtualMailManager/handler.py:732 -#: VirtualMailManager/handler.py:746 VirtualMailManager/handler.py:776 -msgid "Ignored destination addresses:" -msgstr "Ignorierte Ziel-Adressen:" - -#: VirtualMailManager/handler.py:674 VirtualMailManager/handler.py:751 -#: VirtualMailManager/handler.py:895 -#, python-format -msgid "The destination account/alias '%s' does not exist." -msgstr "Das/der Ziel-Konto/-Alias »%s« existiert nicht." - -#: VirtualMailManager/handler.py:696 -#, python-format -msgid "" -"The account has been successfully deleted from the database.\n" -" But an error occurred while deleting the following directory:\n" -" '%(directory)s'\n" -" Reason: %(reason)s" -msgstr "" -"Das Konto wurde erfolgreich aus der Datenbank gelöscht.\n" -" Aber es trat ein Fehler auf beim Löschen des folgenden Verzeichnisses:\n" -" »%(directory)s«\n" -" Grund: %(reason)s" - -#: VirtualMailManager/handler.py:854 -#, python-format -msgid "Could not accept transport: '%s'" -msgstr "Transport kann nicht akzeptiert werden: »%s«" - -#: VirtualMailManager/handler.py:905 VirtualMailManager/relocated.py:106 -#: VirtualMailManager/relocated.py:113 -#, python-format -msgid "The relocated user '%s' does not exist." -msgstr "Der umgezogene Benutzer »%s« existiert nicht." - -#: VirtualMailManager/mailbox.py:260 -#, python-format -msgid "Failed to create mailboxes: %r\n" -msgstr "Postfächer konnten nicht angelegt werden: %r\n" - -#: VirtualMailManager/maillocation.py:74 -msgid "Empty directory name" -msgstr "Verzeichnisname ist leer" - -#: VirtualMailManager/maillocation.py:76 -#, python-format -msgid "Directory name is too long: '%s'" -msgstr "Verzeichnisname ist zu lang: »%s«" - -#: VirtualMailManager/password.py:389 -#, python-format -msgid "Unsupported password scheme: '%s'" -msgstr "Nicht unterstütztes Passwortschema: »%s«" - -#: VirtualMailManager/password.py:392 -#, python-format -msgid "The password scheme '%(scheme)s' requires Dovecot >= v%(version)s." -msgstr "Das Passwortschema »%(scheme)s« benötigt Dovecot >= v%(version)s." - -#: VirtualMailManager/password.py:398 -msgid "Encoding suffixes for password schemes require Dovecot >= v1.1.alpha1." -msgstr "Encoding-Suffixe für Passwort-Schemata benötigen Dovecot >= v1.1.alpha1." - -#: VirtualMailManager/password.py:401 -#, python-format -msgid "Unsupported password encoding: '%s'" -msgstr "Nicht unterstützte Encodierung des Passworts: »%s«" - -#: VirtualMailManager/relocated.py:62 VirtualMailManager/relocated.py:76 -msgid "The destination address' domain name must not be localhost." -msgstr "Der Domainname der Zieladresse darf nicht localhost sein." - -#: VirtualMailManager/relocated.py:79 -msgid "Address and destination are identical." -msgstr "Alias- und Ziel-Adresse sind identisch." - -#: VirtualMailManager/relocated.py:83 -#, python-format -msgid "The relocated user '%s' already exists." -msgstr "Der umgezogene Benutzer »%s« existiert bereits." diff -r 659c4476c57c -r b678a1c43027 po/fi.po --- a/po/fi.po Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1995 +0,0 @@ -# Finnish messages for vmm. -# Copyright © 2010, 2012, 2014 Free Software Foundation, Inc. -# This file is distributed under the same license as the vmm package. -# Jorma Karvonen <karvonen.jorma@gmail.com>, 2010, 2012, 2014. -# -msgid "" -msgstr "" -"Project-Id-Version: vmm 0.6.3-pre1\n" -"Report-Msgid-Bugs-To: user+vmm/tp@localhost.localdomain.org\n" -"POT-Creation-Date: 2014-03-23 20:10+0000\n" -"PO-Revision-Date: 2014-03-24 19:14+0200\n" -"Last-Translator: Jorma Karvonen <karvonen.jorma@gmail.com>\n" -"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n" -"Language: fi\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TP: Hm, what “quotation marks” should be used? -#. If you are unsure have a look at: -#. http://en.wikipedia.org/wiki/Quotation_mark,_non-English_usage -#: VirtualMailManager/account.py:60 VirtualMailManager/alias.py:35 -#: VirtualMailManager/catchall.py:44 VirtualMailManager/domain.py:131 -#: VirtualMailManager/relocated.py:39 -#, python-format -msgid "The domain '%s' does not exist." -msgstr "Verkkotunnus ’%s’ ei ole olemassa." - -#: VirtualMailManager/account.py:123 -#, python-format -msgid "The mailbox format '%(mbfmt)s' requires Dovecot >= v%(version)s." -msgstr "Sähköpostilaatikkomuoto ’%(mbfmt)s’ vaatii Dovecot >= v%(version)s." - -#: VirtualMailManager/account.py:166 VirtualMailManager/cli/handler.py:93 -#: VirtualMailManager/handler.py:683 VirtualMailManager/handler.py:789 -#: VirtualMailManager/handler.py:815 VirtualMailManager/handler.py:823 -#: VirtualMailManager/handler.py:831 VirtualMailManager/handler.py:839 -#: VirtualMailManager/handler.py:858 VirtualMailManager/handler.py:870 -#, python-format -msgid "The account '%s' does not exist." -msgstr "Tiliä ’%s’ ei ole olemassa." - -#: VirtualMailManager/account.py:222 VirtualMailManager/account.py:243 -#: VirtualMailManager/cli/handler.py:77 VirtualMailManager/handler.py:651 -#, python-format -msgid "The account '%s' already exists." -msgstr "Tili ’%s’ on jo olemassa." - -#: VirtualMailManager/account.py:225 VirtualMailManager/handler.py:811 -#, python-format -msgid "Could not accept password: '%s'" -msgstr "Salasanan hyväksyminen epäonnistui: ’%s’" - -#: VirtualMailManager/account.py:246 -#, python-format -msgid "No password set for account: '%s'" -msgstr "Tilille ei ole asetettu salasanaa: ’%s’" - -#: VirtualMailManager/account.py:285 -#, python-format -msgid "Unknown field: '%s'" -msgstr "Tuntematon kenttä: ’%s’" - -#: VirtualMailManager/account.py:307 VirtualMailManager/domain.py:331 -msgid "PostgreSQL-based dictionary quota requires Dovecot >= v1.1.2." -msgstr "PostgreSQL-perustainen sanakirjakiintiö vaatii Dovecot >= v1.1.2" - -#. TP: A service (e.g. pop3 or imap) may be enabled/usable or -#. disabled/unusable for a user. -#: VirtualMailManager/account.py:370 -msgid "disabled" -msgstr "poistettu käytöstä" - -#: VirtualMailManager/account.py:370 -msgid "enabled" -msgstr "otettu käyttöön" - -#: VirtualMailManager/account.py:409 -#, python-format -msgid "Could not fetch information for account: '%s'" -msgstr "Tiedojen noutaminen tilille epäonnistui: ’%s’" - -# Alla "count" ja "address" ovat muuttujia, jotka korvautuvat suorituksen yhteydessä koodilla. -#: VirtualMailManager/account.py:453 -#, python-format -msgid "There are %(count)d aliases with the destination address '%(address)s'." -msgstr "On %(count)d aliasta kohdeosoitteella ’%(address)s’." - -#: VirtualMailManager/account.py:482 -msgid "UID must be an int/long." -msgstr "UID-käyttäjätunnisteen on oltava tyypiltään int/long." - -#: VirtualMailManager/account.py:484 -msgid "UID must be greater than 0." -msgstr "UID-käyttäjätunnisteen on oltava suurempi kuin 0." - -#: VirtualMailManager/account.py:493 -#, python-format -msgid "There is no account with the UID: '%d'" -msgstr "Ei ole tiliä UID-käyttäjätunnisteella: ’%d’" - -# Alla "address" ja "count" ovat muuttuja, jotka korvautuvat suorituksen yhteydessä koodilla. -#: VirtualMailManager/alias.py:61 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"Currently this alias expands into %(count)i/%(limit)i recipients.\n" -"%(count_new)i additional destination(s) will render this alias unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit" -msgstr "" -"Ei voida lisätä %(count_new)i uutta kohdetta aliakselle ’%(address)s’.\n" -"Nykyisin tämä alias laajenee %(count)i/%(limit)i vastaanottajaan.\n" -"%(count_new)i lisäkohdetta tekee tämän aliaksen käyttökelvottomaksi.\n" -"Vihje: Kasvata Postfix-arvoa virtual_alias_expansion_limit" - -#: VirtualMailManager/alias.py:68 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"This alias already exceeds its expansion limit (%(count)i/%(limit)i).\n" -"So its unusable, all messages addressed to this alias will be bounced.\n" -"Hint: Delete some destination addresses." -msgstr "" -"Ei voida lisätä %(count_new)i uutta kohdetta aliakseen ’%(address)s’.\n" -"Tämä alias ylittää jo laajennusrajansa (%(count)i/%(limit)i).\n" -"Joten se on käyttökelvoton. Kaikki tähän aliakseen suunnatut viestit\n" -"ponnahtavat takaisin.\n" -"Vihje: Poista joitakin kohdeosoitteita." - -#: VirtualMailManager/alias.py:155 VirtualMailManager/alias.py:172 -#: VirtualMailManager/alias.py:179 VirtualMailManager/handler.py:712 -#, python-format -msgid "The alias '%s' does not exist." -msgstr "Alias ’%s’ ei ole olemassa." - -#: VirtualMailManager/alias.py:163 -#, python-format -msgid "No suitable destinations left to remove from alias '%s'." -msgstr "Aliakselle ’%s’ ei ole jätetty sopivia kohteita poistettavaksi." - -#: VirtualMailManager/aliasdomain.py:50 -#, python-format -msgid "The domain '%s' is a primary domain." -msgstr "Verkkotunnus ’%s’ on ensisijainen verkkotunnus." - -#: VirtualMailManager/aliasdomain.py:69 -#, python-format -msgid "The alias domain '%s' already exists." -msgstr "Aliasverkkotunnus ’%s’ on jo olemassa." - -#: VirtualMailManager/aliasdomain.py:72 VirtualMailManager/aliasdomain.py:106 -msgid "No destination domain set for the alias domain." -msgstr "Ei kohdeverkkotunnusjoukkoa aliasverkkotunnukselle." - -#: VirtualMailManager/aliasdomain.py:75 VirtualMailManager/aliasdomain.py:109 -#, python-format -msgid "The target domain '%s' does not exist." -msgstr "Kohdeverkkotunnusta ’%s’ ei ole." - -#: VirtualMailManager/aliasdomain.py:88 VirtualMailManager/aliasdomain.py:112 -#: VirtualMailManager/aliasdomain.py:133 -#, python-format -msgid "The alias domain '%s' does not exist." -msgstr "Aliasverkkotunnusta ’%s’ ei ole." - -#: VirtualMailManager/aliasdomain.py:98 -#, python-format -msgid "There is no primary domain for the alias domain '%s'." -msgstr "Ei ole ensisijaista verkkotunnusta aliasverkkotunnukselle ’%s’." - -# Alla "alias" ja "domain" ovat muuttujia, jotka korvautuvat suorituksen yhteydessä koodilla. -#: VirtualMailManager/aliasdomain.py:115 -#, python-format -msgid "The alias domain '%(alias)s' is already assigned to the domain '%(domain)s'." -msgstr "Aliasverkkotunnus ’%(alias)s’ on jo liitetty verkkotunnukseen ’%(domain)s’." - -# Alla "address" ja "count" ovat muuttuja, jotka korvautuvat suorituksen yhteydessä koodilla. -#: VirtualMailManager/catchall.py:69 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to catch-all alias for\n" -"domain '%(domain)s'. Currently this alias expands into %(count)i/%(limit)i\n" -"recipients. %(count_new)i additional destination(s) will render this alias\n" -"unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit" -msgstr "" -"Ei voida lisätä %(count_new)i uutta kohdetta sieppaa-kaikki-aliakselle\n" -"verkkoalueelle ’%(domain)s’. Nykyisin tämä alias laajenee %(count)i/%(limit)i\n" -"vastaanottajaan. %(count_new)i lisäkohdetta tekee tämän aliaksen\n" -"käyttökelvottomaksi.\n" -"Vihje: Kasvata Postfix-arvoa virtual_alias_expansion_limit" - -#: VirtualMailManager/catchall.py:77 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to catch-all alias for domain\n" -"'%(domain)s'. This alias already exceeds its expansion limit (%(count)i/%(limit)i).\n" -"So its unusable, all messages addressed to this alias will be bounced.\n" -"Hint: Delete some destination addresses." -msgstr "" -"Ei voida lisätä %(count_new)i uutta kohdetta sieppaa-kaikki-aliakseen\n" -"verkkoalueelle ’%(domain)s’. Tämä alias ylittää jo laajennusrajansa (%(count)i/%(limit)i).\n" -"Joten se on käyttökelvoton. Kaikki tähän aliakseen suunnatut viestit ponnahtavat takaisin.\n" -"Vihje: Poista joitakin kohdeosoitteita." - -#: VirtualMailManager/catchall.py:151 VirtualMailManager/catchall.py:169 -#: VirtualMailManager/catchall.py:176 -#, python-format -msgid "There are no catch-all aliases defined for domain '%s'." -msgstr "Ei ole sieppaa-kaikki-aliasta verkkotunnukselle ’%s’." - -#: VirtualMailManager/catchall.py:159 -#, python-format -msgid "No suitable destinations left to remove from the catch-all alias of domain '%s'." -msgstr "Verkkotunnuksen ’%s’ sieppaa-kaikki-aliakselle ei ole jätetty sopivia kohteita poistettaviksi." - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:78 -msgid "Enter new password: " -msgstr "Uusi salasana: " - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:80 -msgid "Retype new password: " -msgstr "Uusi salasana uudelleen: " - -#: VirtualMailManager/cli/__init__.py:85 VirtualMailManager/cli/config.py:53 -msgid "Too many failures - try again later." -msgstr "Liian monia häiriöitä - yritä uudelleen myöhemmin." - -#: VirtualMailManager/cli/__init__.py:91 -msgid "Sorry, passwords do not match." -msgstr "Salasanat eivät täsmää." - -#: VirtualMailManager/cli/__init__.py:95 -msgid "Sorry, empty passwords are not permitted." -msgstr "Tyhjät salasanat eivät ole sallittuja." - -#. TP: There are some words enclosed within angle brackets '<'word'>'. They -#. are used to indicate replaceable arguments. Please do not translate them. -#. -#. The descriptions of subcommands may contain the both keywords 'domain' -#. and 'force', enclosed within single quotes. Please keep them as they are. -#. -#. TP: description of subcommand configget -#: VirtualMailManager/cli/clihelp.py:21 -msgid "" -"This subcommand is used to display the actual value\n" -"of the given configuration <option>." -msgstr "" -"Tätä alikomentoa käytetään näyttämään annetun asetusvalitsimen\n" -"<option> todellisen arvon." - -#. TP: description of subcommand configset -#: VirtualMailManager/cli/clihelp.py:24 -msgid "" -"Use this subcommand to set or update a single\n" -"configuration option's value. <option> is the configuration option, <value>\n" -"is the <option>'s new value." -msgstr "" -"Käytä tätä alikomentoa yksittäisen asetusvalitsimen\n" -"asettamiseen tai päivittämiseen. <option> on asetusvalitsin, <value>\n" -"on uusi <option>-arvo." - -#: VirtualMailManager/cli/clihelp.py:27 VirtualMailManager/cli/clihelp.py:42 -msgid "" -"Note: This subcommand will create a new vmm.cfg without any comments.\n" -"Your current configuration file will be backed as vmm.cfg.bak." -msgstr "" -"Huomaa: Tämä alikomento luo uuden vmm.cfg-tiedoston ilman kommentteja.\n" -"Nykyinen asetustiedostosi kopioidaan varakopioksi nimellä vmm.cfg.bak." - -#. TP: description of subcommand configure -#: VirtualMailManager/cli/clihelp.py:30 -msgid "" -"Starts the interactive configuration for all\n" -"configuration sections." -msgstr "" -"Aloittaa vuorovaikutteisen asetustilan kaikille\n" -"asetuslohkoille." - -#: VirtualMailManager/cli/clihelp.py:32 -msgid "" -"In this process the currently set value of each option will be displayed\n" -"in square brackets. If no value is configured, the default value of each\n" -"option will be displayed in square brackets. Press the return key, to accept\n" -"the displayed value." -msgstr "" -"Tässä prosessissa jokaisen valitsimen nykyinen asetettu arvo näytetään\n" -"hakasulkeissa. Jos mitään arvoa ei ole asetettu, hakasulkeissa näytetään\n" -"jokaisen valitsimen oletusarvo. Paina Enter-painiketta näytetyn arvon\n" -"hyväksymiseksi." - -#: VirtualMailManager/cli/clihelp.py:36 -msgid "" -"If the optional argument <section> is given, only the configuration\n" -"options from the given section will be displayed and will be configurable.\n" -"The following sections are available:\n" -msgstr "" -"Jos valinnainen argumentti <section> on annettu, vain annetun lohkon\n" -"valitsimet näytetään ja ne ovat asetettavissa. Seuraavat\n" -"lohkot ovat käytettävissä:\n" - -#: VirtualMailManager/cli/clihelp.py:41 -msgid "All configuration options are described in vmm.cfg(5)." -msgstr "Kaikki asetusvalitsimet on kuvailtu tiedostossa vmm.cfg(5)." - -#. TP: description of subcommand getuser -#: VirtualMailManager/cli/clihelp.py:45 -msgid "" -"If only the <uid> is available, for example from process\n" -"list, the subcommand getuser will show the user's address." -msgstr "" -"Jos vain käyttäjätunniste <uid> on käytettävissä, esimerkiksi\n" -"prosessiluettelosta, alikomento getuser näyttää käyttäjän osoitteen." - -#. TP: description of subcommand listaddresses -#: VirtualMailManager/cli/clihelp.py:48 -msgid "" -"This command lists all defined addresses.\n" -"Addresses belonging to alias-domains are prefixed with a '-', addresses of\n" -"regular domains with a '+'. Additionally, the letters 'u', 'a', and 'r'\n" -"indicate the type of each address: user, alias and relocated respectively.\n" -"The output can be limited with an optional <pattern>." -msgstr "" -"Tämä komento luetteloi kaikki määritellyt osoitteet.\n" -"Aliasverkkotunnuksiin kuuluvilla osoitteilla on etuliite ’-’, tavallisilla\n" -"verkkotunnuksilla etuliite ’+’. Lisäksi kirjaimet ’u’, ’a’, ja ’r’ osoittavat\n" -"vastaavasti jokaisen osoitteen tyypin: käyttäjä, alias ja sijoitettu.\n" -"Tulostusta voidaan rajoittaa valinnaisella valitsimella <pattern>." - -#: VirtualMailManager/cli/clihelp.py:53 VirtualMailManager/cli/clihelp.py:60 -#: VirtualMailManager/cli/clihelp.py:67 VirtualMailManager/cli/clihelp.py:82 -#: VirtualMailManager/cli/clihelp.py:88 -#, no-python-format -msgid "" -"To perform a wild card search, the % character can be used at the start\n" -"and/or the end of the <pattern>." -msgstr "" -"Jokerimerkkihaun suorittamiseksi merkkiä % voidaan käyttää valitsimen <pattern>\n" -"alussa ja/tai lopussa." - -#. TP: description of subcommand listaliases -#: VirtualMailManager/cli/clihelp.py:56 -msgid "" -"This command lists all defined aliases. Aliases\n" -"belonging to alias-domains are prefixed with a '-', addresses of regular\n" -"domains with a '+'. The output can be limited with an optional <pattern>." -msgstr "" -"Tämä komento luetteloi kaikki käytettävissä olevat aliakset. Aliasverkkotunnuksiin\n" -"kuuluvilla aliaksilla on etuliite ’[-]’, tavallisilla verkkotunnuksilla etuliite ’[+]’.\n" -"Tulostusta voidaan rajoittaa valinnaisella valitsimella <pattern>." - -#. TP: description of subcommand listdomains -#: VirtualMailManager/cli/clihelp.py:63 -msgid "" -"This subcommand lists all available domains. All\n" -"domain names will be prefixed either with `[+]', if the domain is a primary\n" -"domain, or with `[-]', if it is an alias domain name. The output can be\n" -"limited with an optional <pattern>." -msgstr "" -"Tämä alikomento luetteloi kaikki käytettävissä olevat verkkotunnukset.\n" -"Kaikkia verkkotunnuksia edeltää joko ”[+]”, jos verkkotunnus on ensisijainen\n" -"verkkotunnus, tai ”[-]”, jos se on aliasverkkotunnus. Tulostusta voidaan\n" -"rajoittaa valinnaisella valitsimella <pattern>." - -#. TP: description of subcommand listpwschemes -#: VirtualMailManager/cli/clihelp.py:70 -msgid "" -"This subcommand lists all password schemes which\n" -"could be used in the vmm.cfg as value of the misc.password_scheme option.\n" -"The output varies, depending on the used Dovecot version and the system's\n" -"libc." -msgstr "" -"Tämä alikomento luettelee kaikki salasanakaavat, joita\n" -"voitaisiin käyttää vmm.cfg-tiedostossa valitsimen misc.password_scheme\n" -"arvona. Tulostus vaihtelee riippuen käytetystä Dovecot-versiosta ja\n" -"järjestelmän libc-kirjastosta. " - -#: VirtualMailManager/cli/clihelp.py:74 -msgid "" -"When your Dovecot installation isn't too old, you will see additionally\n" -"a few usable encoding suffixes. One of them can be appended to the password\n" -"scheme." -msgstr "" -"Kun Dovecot-asennuksesi ei ole liian vanha, näet lisäksi muutamia\n" -"käyttäkelpoisia koodausloppuliitteitä. Yksi niistä voidaan liittää salasana-\n" -"kaavaan." - -#. TP: description of subcommand listrelocated -#: VirtualMailManager/cli/clihelp.py:78 -msgid "" -"This command lists all defined relocated addresses.\n" -"Relocated entries belonging to alias-domains are prefixed with a '-', addresses\n" -"of regular domains with a '+'. The output can be limited with an optional\n" -"<pattern>." -msgstr "" -"Tämä komento luetteloi kaikki käytettävissä olevat sijoitusosoitteet.\n" -"Sijoitusosoitteisiin kuuluvilla alias-verkkotunnuksilla on etuliite ’-’,\n" -"tavallisilla sijoitusosoitteilla etuliite ’+’. Tulostusta voidaan rajoittaa\n" -"valinnaisella valitsimella <pattern>." - -#. TP: description of subcommand listusers -#: VirtualMailManager/cli/clihelp.py:85 -msgid "" -"This command lists all user accounts. User accounts\n" -"belonging to alias-domains are prefixed with a '-', addresses of regular\n" -"domains with a '+'. The output can be limited with an optional <pattern>." -msgstr "" -"Tämä komento luetteloi kaikki käyttäjätilit. Aliasverkkotunnuksiin kuuluvilla\n" -"käyttäjätileillä on etuliite ’-’, tavallisilla verkkotunnuksilla etuliite\n" -"’+’. Tulostusta voidaan rajoittaa valinnaisella valitsimella <pattern>." - -#. TP: description of subcommand version -#: VirtualMailManager/cli/clihelp.py:91 -msgid "" -"Prints vmm's version and copyright information to stdout.\n" -"After this vmm exits." -msgstr "" -"Tulostaa vmm:n version ja copyright-tiedot vakiotulosteeseen.\n" -"Tämän jälkeen vmm sulkeutuu." - -#. TP: description of subcommand domainadd -#: VirtualMailManager/cli/clihelp.py:94 -msgid "" -"Adds the new domain into the database and creates the\n" -"domain directory." -msgstr "" -"Lisää uuden verkkotunnuksen tietokantaan ja luo\n" -"verkkotunnushakemiston." - -#: VirtualMailManager/cli/clihelp.py:96 -msgid "" -"If the optional argument <transport> is given, it will override the\n" -"default transport (domain.transport) from vmm.cfg. The specified <transport>\n" -"will be the default transport for all new accounts in this domain." -msgstr "" -"Jos valinnainen argumentti <transport> on annettu, se korvaa\n" -"oletus-transport-argumentin (domain.transport) tiedostosta vmm.cfg.\n" -"Määritelty <transport> on oletus-transport-argumentti kaikille tämän\n" -"verkkotunnuksen uusille tileille." - -#: VirtualMailManager/cli/clihelp.py:99 -msgid "Configuration-related behavior:" -msgstr "Asetuskohtainen käyttäytyminen:" - -#: VirtualMailManager/cli/clihelp.py:101 -msgid "" -"When that option is set to true (default) vmm will automatically create\n" -"the postmaster account for the new domain and prompt for postmaster@<fqdn>'s\n" -"password." -msgstr "" -"Kun tuo valitsin asetetaan arvoon true (oletus), vmm luo automaattisesti\n" -"postimestari-tilin uudelle verkkotunnukselle ja kysyy postmaster@<fqdn>-\n" -"salasanaa." - -#: VirtualMailManager/cli/clihelp.py:105 -msgid "" -"When the value of that option is also set to true, vmm will automatically\n" -"create the postmaster account for the new domain and print the generated\n" -"postmaster password to stdout." -msgstr "" -"Kun tuo valitsin asetetaan myös arvoon true, vmm luo automaattisesti\n" -"postimestari-tilin uudelle verkkotunnukselle ja tulostaa tuotetun\n" -"postmaster-salasanan vakiotulosteeseen." - -#. TP: description of subcommand domaindelete -#: VirtualMailManager/cli/clihelp.py:109 -msgid "" -"This subcommand deletes the domain specified by\n" -"<fqdn>." -msgstr "" -"Tämä alikomento poistaa <fqdn>:n määrittelemän\n" -"verkkotunnuksen." - -#: VirtualMailManager/cli/clihelp.py:111 -msgid "" -"If there are accounts, aliases and/or relocated users assigned to the\n" -"given domain, vmm will abort the requested operation and show an error\n" -"message. If you know, what you are doing, you can specify the optional keyword\n" -"'force'." -msgstr "" -"Jos annettuun verkkotunnukseen on liitetty tilejä, aliaksia ja/tai sijoitettuja\n" -"käyttäjiä, vmm keskeyttää pyydetyn toiminnon ja näyttää virheilmoituksen.\n" -"Jos tiedät, mitä olet tekemässä, voit määritellä valinnaisen avainsanan\n" -"’force’." - -#: VirtualMailManager/cli/clihelp.py:115 -msgid "" -"If you really always know what you are doing, edit your vmm.cfg and set\n" -"the option domain.force_deletion to true." -msgstr "" -"Jos aina todella tiedät, mitä olet tekemässä, muokkaa tiedostoa vmm.cfg\n" -"ja aseta valitsin domain.force_deletion arvoon true." - -#. TP: description of subcommand domaininfo -#: VirtualMailManager/cli/clihelp.py:118 -msgid "" -"This subcommand shows some information about the\n" -"given domain." -msgstr "" -"Tämä alikomento näyttää joitain tietoja annetusta\n" -"verkkotunnuksesta." - -#: VirtualMailManager/cli/clihelp.py:120 -msgid "" -"For a more detailed information about the domain the optional argument\n" -"<details> can be specified. A possible <details> value can be one of the\n" -"following six keywords:" -msgstr "" -"Yksityiskohtaisempia verkkotunnustietoja varten voidaan määritellä\n" -"valinnainen argumentti <details>. Mahdollinen <details>-arvo voi olla\n" -"yksi seuraavista kuudesta avainsanasta:" - -#. TP: description of subcommand domainquota -#: VirtualMailManager/cli/clihelp.py:125 -msgid "" -"This subcommand is used to configure a new quota\n" -"limit for the accounts of the domain - not for the domain itself." -msgstr "" -"Tätä alikomentoa käytetään asettamaan uusi kiintiöraja\n" -"verkkotunnuksen tileille - ei verkkotunnukselle itselle." - -#: VirtualMailManager/cli/clihelp.py:127 -msgid "" -"The default quota limit for accounts is defined in the vmm.cfg\n" -"(domain.quota_bytes and domain.quota_messages)." -msgstr "" -"Tilien oletuskiintiöraja on määritelty tiedostossa vmm.cfg\n" -"(domain.quota_bytes ja domain.quota_messages)." - -#: VirtualMailManager/cli/clihelp.py:129 -msgid "" -"The new quota limit will affect only those accounts for which the limit\n" -"has not been overridden. If you want to restore the default to all accounts,\n" -"you may pass the keyword 'force'. When the argument <messages> was omitted the\n" -"default number of messages 0 (zero) will be applied." -msgstr "" -"Uusi kiintiöraja vaikuttaa vain niihin tileihin, joiden rajaa ei ole ylitetty.\n" -"Jos haluat palauttaa oletuksen kaikkiin tileihin, voit käyttää avainsanaa\n" -"’force’. Kun argumentti <messages> ohitettiin, viestien oletusmääränä\n" -"käytetään 0 (nolla)." - -#. TP: description of subcommand domainservices -#: VirtualMailManager/cli/clihelp.py:134 -msgid "" -"To define which services could be used by the\n" -"users of the domain — with the given <fqdn> — use this subcommand." -msgstr "" -"Käytä tätä alikomentoa määrittämään, että mitä palveluja\n" -"verkkotunnuksen käyttäjät — annetulla <fqdn>:lla — voivat käyttää." - -#: VirtualMailManager/cli/clihelp.py:136 -msgid "" -"Each specified <service> will be enabled/usable. All other services\n" -"will be deactivated/unusable. Possible <service> names are:" -msgstr "" -"Jokainen määritelty <service>-palvelu on käyttöön otetettava/käytettävä.\n" -"Kaikki muut palvelut ovat ei-aktiivisia/käyttökelvottomia. Mahdollisia\n" -"<service>-palvelunimiä ovat:" - -#: VirtualMailManager/cli/clihelp.py:139 -msgid "" -"The new service set will affect only those accounts for which the set has\n" -"not been overridden. If you want to restore the default to all accounts, you\n" -"may pass the keyword 'force'." -msgstr "" -"Uusi palvelujoukko vaikuttaa vain niihin tileihin, joissa joukko ei ole korvattu.\n" -"Jos haluat palauttaa oletusarvon kaikkiin tileihin, voit välittää avainsanan\n" -"’force’." - -#. TP: description of subcommand domaintransport -#: VirtualMailManager/cli/clihelp.py:143 -msgid "" -"A new transport for the indicated domain can be\n" -"set with this subcommand." -msgstr "" -"Tällä alikomennolla voidaan asettaa siirto ilmoitettuun\n" -"verkkotunnukseen." - -#: VirtualMailManager/cli/clihelp.py:145 -msgid "" -"The new transport will affect only those accounts for which the transport\n" -"has not been overridden. If you want to restore the default to all accounts,\n" -"you may pass the keyword 'force'." -msgstr "" -"Uusi siirto vaikuttaa vain niihin tileihin, joiden siirtoa\n" -"ei ole korvattu. Jos haluat palauttaa oletusasetuksen kaikkiin\n" -"tileihin, voit välittää avainsanan ’force’." - -#. TP: description of subcommand domainnote -#: VirtualMailManager/cli/clihelp.py:149 -msgid "" -"With this subcommand, it is possible to attach a\n" -"note to the specified domain. Without an argument, an existing note is\n" -"removed." -msgstr "" -"Tällä alikomennolla on mahdollista liittää muistio\n" -"määriteltyyn verkkotunnukseen. Ilman argumenttia olemassa oleva\n" -"muistio poistetaan." - -#. TP: description of subcommand aliasdomainadd -#: VirtualMailManager/cli/clihelp.py:153 -msgid "" -"This subcommand adds the new alias domain\n" -"(<fqdn>) to the destination <domain> that should be aliased." -msgstr "" -"Tämä alikomento lisää uuden aliasverkkotunnuksen (<fqdn>)\n" -"kohde-<domain>-verkkotunnukseen, josta pitäisi tehdä alias." - -#. TP: description of subcommand aliasdomaindelete -#: VirtualMailManager/cli/clihelp.py:156 -msgid "" -"Use this subcommand if the alias domain\n" -"<fqdn> should be removed." -msgstr "" -"Käytä tätä alikomentoa, jos alias-verkkotunnus\n" -"<fqdn> olisi poistettava." - -#. TP: description of subcommand aliasdomaininfo -#: VirtualMailManager/cli/clihelp.py:159 -msgid "" -"This subcommand shows to which domain the alias\n" -"domain <fqdn> is assigned to." -msgstr "" -"Tämä alikomento näyttää, että mihin verkkotunnukseen\n" -"verkkotunnus <fqdn> on liitetty." - -#. TP: description of subcommand aliasdomainswitch -#: VirtualMailManager/cli/clihelp.py:162 -msgid "" -"If the destination of the existing alias\n" -"domain <fqdn> should be switched to another <destination> use this\n" -"subcommand." -msgstr "" -"Käytä tätä alikomentoa, jos olemassa oleva alias-\n" -"verkkotunnus <fqdn> olisi vaihdettava toiseen <destination>-\n" -"verkkotunnukseen." - -#. TP: description of subcommand useradd -#: VirtualMailManager/cli/clihelp.py:166 -msgid "" -"Use this subcommand to create a new e-mail account for\n" -"the given <address>." -msgstr "" -"Käytä tätä alikomentoa luomaan uusi sähköpostitili\n" -"annetulla osoitteelle <address>." - -#: VirtualMailManager/cli/clihelp.py:168 -msgid "" -"If the <password> is not provided, vmm will prompt for it interactively.\n" -"When no <password> is provided and account.random_password is set to true, vmm\n" -"will generate a random password and print it to stdout after the account has\n" -"been created." -msgstr "" -"Jos <password> tarjotaan, vmm kyselee sitä vuorovaikutteisesti.\n" -"Kun mitään <password> ei ole tarjottu ja account.random_password\n" -"on asetettu arvoon true, vmm tuottaa satunnaisen salasanan ja tulostaa\n" -"sen vakiotulosteeseen tilin luomisen jälkeen." - -#. TP: description of subcommand userdelete -#: VirtualMailManager/cli/clihelp.py:173 -msgid "" -"Use this subcommand to delete the account with the\n" -"given <address>." -msgstr "" -"Käytä tätä alikomentoa poistamaan tili annetusta\n" -"osoitteesta <address>." - -#: VirtualMailManager/cli/clihelp.py:175 -msgid "" -"If there are one or more aliases with an identical destination address,\n" -"vmm will abort the requested operation and show an error message. To prevent\n" -"this, specify the optional keyword 'force'." -msgstr "" -"Jos samassa kohdeosoitteessa on yksi tai useampia aliasosoitteita,\n" -"vmm keskeyttää pyydetyn toiminnon ja näyttää virheilmoituksen. Tämän\n" -"estämiseksi määritä avainsana ’force’." - -#. TP: description of subcommand userinfo -#: VirtualMailManager/cli/clihelp.py:179 -msgid "" -"This subcommand displays some information about the\n" -"account specified by <address>." -msgstr "" -"Tämä alikomento näyttää joitain tietoja osoitteen\n" -"<address> määrittämästä tilistä." - -#: VirtualMailManager/cli/clihelp.py:181 -msgid "" -"If the optional argument <details> is given some more information will be\n" -"displayed. Possible values for <details> are:" -msgstr "" -"Jos annetaan valinnainen argumentti <details>, niin näytetään joitain\n" -"lisätietoja. Mahdollisia <details>-arvoja ovat:" - -#. TP: description of subcommand username -#: VirtualMailManager/cli/clihelp.py:185 -msgid "" -"The user's real <name> can be set/updated with this\n" -"subcommand." -msgstr "" -"Tällä alikomennolla voidaan asettaa/päivittää\n" -"käyttäjän oikea nimi <name>." - -#: VirtualMailManager/cli/clihelp.py:187 -msgid "If no <name> is given, the value stored for the account is erased." -msgstr "Jos mitään nimeä <name> ei anneta, tiliin tallennettu arvo poistetaan." - -#. TP: description of subcommand userpassword -#: VirtualMailManager/cli/clihelp.py:190 -msgid "" -"The password of an account can be updated with this\n" -"subcommand." -msgstr "Tällä alikomennolla voidaan päivittää tilin salasana." - -#: VirtualMailManager/cli/clihelp.py:192 -msgid "If no <password> was provided, vmm will prompt for it interactively." -msgstr "Jos mitään salasanaa <password> ei tarjota, vmm kyselee sen vuorovaikutteisesti." - -#. TP: description of subcommand usernote -#: VirtualMailManager/cli/clihelp.py:195 -msgid "" -"With this subcommand, it is possible to attach a note\n" -"to the specified account. Without an argument, an existing note is\n" -"removed." -msgstr "" -"Tällä alikomennolla on mahdollista liittää muistiinpano\n" -"määriteltyyn tiliin. Ilman argumenttia olemassa muistiinpano\n" -"poistetaan." - -#. TP: description of subcommand userquota -#: VirtualMailManager/cli/clihelp.py:199 -msgid "" -"This subcommand is used to set a new quota limit for\n" -"the given account." -msgstr "" -"Tätä alikomentoa käytetään asettamaan uusi kiintiöraja\n" -"tietylle tilille." - -#: VirtualMailManager/cli/clihelp.py:201 -msgid "" -"When the argument <messages> was omitted the default number of messages\n" -"0 (zero) will be applied." -msgstr "" -"Kun ohitetaan argumentti <messages>, käytetään viestien\n" -"oletuslukumäärää 0 (nolla)." - -#: VirtualMailManager/cli/clihelp.py:203 -msgid "" -"Instead of <storage> pass the keyword 'domain' to remove the\n" -"account-specific override, causing the domain's value to be in effect." -msgstr "" -"Argumentin <storage> sijasta avainsanan ’domain’ välittäminen\n" -"poistaa tilikohtaisen korvauksen, mikä tuo verkkotunnuksen arvon voimaan." - -#. TP: description of subcommand userservices -#: VirtualMailManager/cli/clihelp.py:206 -msgid "" -"To grant a user access to the specified services,\n" -"use this command." -msgstr "" -"Käytä tätä komentoa käyttäjäoikeuksien myöntämiseksi\n" -"määriteltyihin palveluihin." - -#: VirtualMailManager/cli/clihelp.py:208 -msgid "" -"All omitted services will be deactivated/unusable for the user with the\n" -"given <address>." -msgstr "" -"Kaikki ohitetut palvelut ovat ei-aktiivisia/käyttökelvottomia\n" -"käyttäjälle tietyllä osoitteella <address>." - -#: VirtualMailManager/cli/clihelp.py:210 -msgid "" -"Instead of <service> pass 'domain' to remove the account-specific\n" -"override, causing the domain's value to be in effect." -msgstr "" -"Argumentin <service> sijasta avainsanan ’domain’ välittäminen\n" -"poistaa tilikohtaisen korvauksen, mikä tuo verkkotunnuksen\n" -"arvon voimaan." - -#. TP: description of subcommand usertransport -#: VirtualMailManager/cli/clihelp.py:213 -msgid "" -"A different <transport> for an account can be\n" -"specified with this subcommand." -msgstr "" -"Tällä alikomennolla voidaan määritellä tilille\n" -"erilainen argumentti <transport>." - -#: VirtualMailManager/cli/clihelp.py:215 -msgid "" -"Instead of <transport> pass 'domain' to remove the account-specific\n" -"override, causing the domain's value to be in effect." -msgstr "" -"Argumentin <transport> sijasta avainsanan ’domain’ välittäminen\n" -"poistaa tilikohtaisen korvauksen, mikä tuo verkkotunnuksen arvon voimaan." - -#. TP: description of subcommand aliasadd -#: VirtualMailManager/cli/clihelp.py:218 -msgid "" -"This subcommand is used to create a new alias\n" -"<address> with one or more <destination> addresses." -msgstr "" -"Tätä alikomentoa käytetään luomaan uusia alias-\n" -"<address>-osoitteita yhdellä tai useammalla\n" -"<destination>-kohdeosoitteella." - -#: VirtualMailManager/cli/clihelp.py:220 -msgid "" -"Within the destination address, the placeholders '%n', '%d', and '%='\n" -"will be replaced by the local part, the domain, or the email address with '@'\n" -"replaced by '=' respectively. In combination with alias domains, this enables\n" -"domain-specific destinations." -msgstr "" -"Kohdeosoitteen sisällä paikkakorvaukset ’%n’, ’%d’, ja ’%=’\n" -"korvaavat paikallisen osan, verkkotunnuksen, tai sähköpostiosoitteen merkki ’@’\n" -"korvataan vastaavasti merkillä ’=’. Yhdessä aliasverkkotunnuksen kanssa\n" -"tämä ottaa käyttöön verkkotunnuskohtaiset kohteet." - -#. TP: description of subcommand aliasdelete -#: VirtualMailManager/cli/clihelp.py:225 -msgid "" -"This subcommand is used to delete one or multiple\n" -"<destination>s from the alias with the given <address>." -msgstr "" -"Tätä alikomentoa käytetään poistamaan yksi tai useita\n" -"<destination>-kohteita tietyn <address>-osoitteen aliaksista." - -#: VirtualMailManager/cli/clihelp.py:227 -msgid "" -"When no <destination> address was specified the alias with all its\n" -"destinations will be deleted." -msgstr "" -"Kun yhtään <destination>-osoitetta ei ole määritelty, alias kaikkine\n" -"kohteineen poistetaan." - -#. TP: description of subcommand aliasinfo -#: VirtualMailManager/cli/clihelp.py:230 -msgid "" -"Information about the alias with the given <address>\n" -"can be displayed with this subcommand." -msgstr "" -"Tällä alikomennolla voidaan näyttää tietoja tietyn\n" -"osoitteen <address> aliaksesta." - -#. TP: description of subcommand relocatedadd -#: VirtualMailManager/cli/clihelp.py:233 -msgid "" -"A new relocated user can be created with this\n" -"subcommand." -msgstr "" -"Tällä alikomennolla voidaan luoda uusi sijoitettu\n" -"käyttäjä." - -#: VirtualMailManager/cli/clihelp.py:235 -msgid "" -"<address> is the user's ex-email address, for example\n" -"b.user@example.com, and <newaddress> points to the new email address where\n" -"the user can be reached." -msgstr "" -"<address> on käyttäjän entinen sähköpostiosoite, esimerkiksi\n" -"b.user@example.com, ja <newaddress> osoittaa uuteen sähköpostiosoitteeseen,\n" -"josta käyttäjä tavoitetaan." - -#. TP: description of subcommand relocatedinfo -#: VirtualMailManager/cli/clihelp.py:239 -msgid "" -"This subcommand shows the new address of the\n" -"relocated user with the given <address>." -msgstr "" -"Tämä alikomento näyttää sijoitetun käyttäjän uuden\n" -"osoitteen annetulla <address>-osoitteella." - -#. TP: description of subcommand relocateddelete -#: VirtualMailManager/cli/clihelp.py:242 -msgid "" -"Use this subcommand in order to delete the\n" -"relocated user with the given <address>." -msgstr "" -"Tätä alikomentoa käytetään poistamaan sijoitettu\n" -"käyttäjä annetulla <address>-osoitteella." - -#. TP: description of subcommand catchalladd -#: VirtualMailManager/cli/clihelp.py:245 -msgid "" -"This subcommand allows to specify destination\n" -"addresses for a domain, which shall receive mail addressed to unknown\n" -"local-parts within that domain. Those catch-all aliases hence \"catch all\" mail\n" -"to any address in the domain (unless a more specific alias, mailbox or\n" -"relocated user exists)." -msgstr "" -"Tämä alikomento sallii määritellä kohdeosoitteita\n" -"verkkotunnukselle, jonka pitäisi vastaanottaa sähköpostin tuntemattomille\n" -"tuon verkkotunnuksen sisäisille paikallisosille. Nuo sieppaa-kaikki-\n" -"aliakset siten \"sieppaavat kaiken\" sähköpostin mihin tahansa verkkotunnuksen\n" -"osoitteeseen (ellei tarkemmin määriteltyä alias-, sähköpostilaatikko-\n" -"tai siirrettyä käyttäjää ole olemassa=." - -#: VirtualMailManager/cli/clihelp.py:250 -msgid "" -"WARNING: Catch-all addresses can cause mail server flooding because\n" -"spammers like to deliver mail to all possible combinations of names, e.g.\n" -"to all addresses between abba@example.org and zztop@example.org." -msgstr "" -"VAROITUS: Sieppaa-kaikki-osoitteet voivat aiheuttaa sähköpostipalvelimen\n" -"tulvimisen, koska roskapostittajat lähetävät mielellään postia kaikkiin\n" -"mahdollisiin nimien yhdistelmiin, esimerkiksi kaikkiin osoitteisiin\n" -"välillä abba@example.org ... zztop@example.org." - -#. TP: description of subcommand catchallinfo -#: VirtualMailManager/cli/clihelp.py:254 -msgid "" -"This subcommand displays information about catch-all\n" -"aliases defined for the domain <fqdn>." -msgstr "" -"Tämä alikomento näyttää tietoja sieppaa-kaikki-\n" -"aliaksesta, jonka verkkotunnus <fqdn> määrittää." - -#. TP: description of subcommand catchalldelete -#: VirtualMailManager/cli/clihelp.py:257 -msgid "" -"With this subcommand, catch-all aliases defined\n" -"for a domain can be removed, either all of them, or those <destination>s which\n" -"were specified explicitly." -msgstr "" -"Tällä alikomennolla voidaan poistaa verkkotunnukselle\n" -"määritellyt sieppaa-kaikki-aliakset, joko ne kaikki, tai ne\n" -"<destination>-osoitteet, jotka on määritelty eksplisiittisesti." - -# Alla "opt" ja "val" ovat muuttujia, jotka korvautuvat suorituksen yhteydessä koodilla. -#: VirtualMailManager/cli/config.py:32 -#, python-format -msgid "Enter new value for option %(option)s [%(current_value)s]: " -msgstr "Uusi arvo valitsimelle %(option)s [%(current_value)s]: " - -#: VirtualMailManager/cli/config.py:36 -#, python-format -msgid "Using configuration file: %s\n" -msgstr "Käytetään asetustiedostoa: %s\n" - -#: VirtualMailManager/cli/config.py:38 -#, python-format -msgid "* Configuration section: '%s'" -msgstr "* Asetuslohko: ’%s’" - -#: VirtualMailManager/cli/config.py:50 -#, python-format -msgid "Warning: %s" -msgstr "Varoitus: %s" - -#: VirtualMailManager/cli/handler.py:66 -#, python-format -msgid "Invalid section: '%s'" -msgstr "Virheellinen lohko: ’%s’" - -#: VirtualMailManager/cli/main.py:32 VirtualMailManager/cli/main.py:67 -#: VirtualMailManager/cli/main.py:70 VirtualMailManager/cli/subcommands.py:756 -#: VirtualMailManager/cli/subcommands.py:776 -#, python-format -msgid "Error: %s" -msgstr "Virhe: %s" - -#: VirtualMailManager/cli/main.py:41 -msgid "You must specify a subcommand at least." -msgstr "Sinun on määriteltävä vähintään alikomento." - -#: VirtualMailManager/cli/main.py:53 -#, python-format -msgid "Unknown subcommand: '%s'" -msgstr "Tuntematon alikomento: ’%s’" - -#. TP: We have to cry, because root has killed/interrupted vmm -#. with Ctrl+C or Ctrl+D. -#: VirtualMailManager/cli/main.py:62 -msgid "Ouch!" -msgstr "Auh!" - -#: VirtualMailManager/cli/main.py:66 VirtualMailManager/cli/main.py:79 -msgid "Warnings:" -msgstr "Varoitukset:" - -#: VirtualMailManager/cli/main.py:73 -#, python-format -msgid "Error: Unknown section: '%s'" -msgstr "Virhe: Tuntematon lohko: ’%s’" - -#: VirtualMailManager/cli/main.py:76 -#, python-format -msgid "Error: No option '%(option)s' in section: '%(section)s'" -msgstr "Virhe: Ei valitsinta ’%(option)s’ lohkossa: ’%(section)s’" - -#: VirtualMailManager/cli/subcommands.py:101 -#, python-format -msgid "Subcommand '%s' is not yet documented." -msgstr "Alikomentoa ’%s’ ei ole vielä dokumentoitu." - -#: VirtualMailManager/cli/subcommands.py:108 -#, python-format -msgid "Plan A failed ... trying Plan B: %(subcommand)s %(object)s" -msgstr "Suunnitelma A epäonnistui ... yritetään suunnitelmaa B: %(subcommand)s %(object)s" - -#: VirtualMailManager/cli/subcommands.py:122 -msgid "Missing alias address and destination." -msgstr "Puuttuva aliasosoite ja -kohde." - -#: VirtualMailManager/cli/subcommands.py:125 -#: VirtualMailManager/cli/subcommands.py:212 -#: VirtualMailManager/cli/subcommands.py:559 -msgid "Missing destination address." -msgstr "Puuttuva kohdeosoite." - -#: VirtualMailManager/cli/subcommands.py:132 -#: VirtualMailManager/cli/subcommands.py:142 -msgid "Missing alias address." -msgstr "Puuttuva aliasosoite." - -#: VirtualMailManager/cli/subcommands.py:164 -#: VirtualMailManager/cli/subcommands.py:198 -msgid "Missing alias domain name and destination domain name." -msgstr "Puuttuva aliasverkkotunnusnimi ja kohdeverkkotunnusnimi." - -#: VirtualMailManager/cli/subcommands.py:167 -#: VirtualMailManager/cli/subcommands.py:201 -msgid "Missing destination domain name." -msgstr "Puuttuva kohdeverkkotunnuksen nimi." - -#: VirtualMailManager/cli/subcommands.py:175 -#: VirtualMailManager/cli/subcommands.py:182 -msgid "Missing alias domain name." -msgstr "Puuttuva aliasverkkotunnuksen nimi." - -#: VirtualMailManager/cli/subcommands.py:209 -msgid "Missing domain and destination." -msgstr "Puuttuva verkkotunnus ja kohde." - -#: VirtualMailManager/cli/subcommands.py:219 -#: VirtualMailManager/cli/subcommands.py:229 -#: VirtualMailManager/cli/subcommands.py:271 -#: VirtualMailManager/cli/subcommands.py:287 -#: VirtualMailManager/cli/subcommands.py:300 -#: VirtualMailManager/cli/subcommands.py:394 -#: VirtualMailManager/cli/subcommands.py:443 -msgid "Missing domain name." -msgstr "Puuttuva verkkotunnusnimi." - -#: VirtualMailManager/cli/subcommands.py:237 -msgid "Missing option name." -msgstr "Puuttuva valitsinnimi." - -#: VirtualMailManager/cli/subcommands.py:253 -msgid "Missing option and new value." -msgstr "Puuttuva valitsin ja uusi arvo." - -#: VirtualMailManager/cli/subcommands.py:255 -msgid "Missing new configuration value." -msgstr "Puuttuva uusi asetusarvo." - -#: VirtualMailManager/cli/subcommands.py:277 -#, python-format -msgid "Creating account for postmaster@%s" -msgstr "Luodaan tili postmaster@%s-osoitteelle" - -#: VirtualMailManager/cli/subcommands.py:293 -#: VirtualMailManager/cli/subcommands.py:307 -#: VirtualMailManager/cli/subcommands.py:385 -#: VirtualMailManager/cli/subcommands.py:406 -#: VirtualMailManager/cli/subcommands.py:435 -#: VirtualMailManager/cli/subcommands.py:615 -#: VirtualMailManager/cli/subcommands.py:628 VirtualMailManager/handler.py:459 -#: VirtualMailManager/handler.py:472 VirtualMailManager/handler.py:487 -#: VirtualMailManager/handler.py:521 VirtualMailManager/handler.py:784 -#, python-format -msgid "Invalid argument: '%s'" -msgstr "Virheellinen argumentti: ’%s’" - -#: VirtualMailManager/cli/subcommands.py:326 -#: VirtualMailManager/cli/subcommands.py:333 -msgid "Domain" -msgstr "Verkkotunnus" - -#: VirtualMailManager/cli/subcommands.py:335 -#: VirtualMailManager/cli/subcommands.py:346 -msgid "accounts" -msgstr "tilit" - -#: VirtualMailManager/cli/subcommands.py:337 -#: VirtualMailManager/cli/subcommands.py:345 -#: VirtualMailManager/cli/subcommands.py:1007 -msgid "alias domains" -msgstr "aliasverkkotunnukset" - -#: VirtualMailManager/cli/subcommands.py:339 -#: VirtualMailManager/cli/subcommands.py:347 -#: VirtualMailManager/cli/subcommands.py:1077 -msgid "aliases" -msgstr "aliakset" - -#: VirtualMailManager/cli/subcommands.py:341 -#: VirtualMailManager/cli/subcommands.py:348 -#: VirtualMailManager/cli/subcommands.py:1078 -msgid "relocated users" -msgstr "sijoitetut käyttäjät" - -#: VirtualMailManager/cli/subcommands.py:343 -#: VirtualMailManager/cli/subcommands.py:349 -msgid "catch-all destinations" -msgstr "sieppaa-kaikki-kohteet" - -#: VirtualMailManager/cli/subcommands.py:355 -msgid "Missing domain name and storage value." -msgstr "Puuttuva verkkotunnusnimi ja tallennusarvo." - -#: VirtualMailManager/cli/subcommands.py:358 -#: VirtualMailManager/cli/subcommands.py:706 -msgid "Missing storage value." -msgstr "Puuttuva tallennusarvo." - -#: VirtualMailManager/cli/subcommands.py:364 -#: VirtualMailManager/cli/subcommands.py:711 -#, python-format -msgid "Invalid storage value: '%s'" -msgstr "Virheellinen argumentti: ’%s’" - -#: VirtualMailManager/cli/subcommands.py:374 -#, python-format -msgid "Neither a valid number of messages nor the keyword 'force': '%s'" -msgstr "Ei ole kelvollinen viestien lukumäärä eikä avainsana ’force’: ’%s’" - -#: VirtualMailManager/cli/subcommands.py:382 -#: VirtualMailManager/cli/subcommands.py:722 -#, python-format -msgid "Not a valid number of messages: '%s'" -msgstr "Viestien lukumäärä ei ole kelvollinen: ’%s’" - -#: VirtualMailManager/cli/subcommands.py:417 -#: VirtualMailManager/cli/subcommands.py:736 -#, python-format -msgid "Invalid service arguments: %s" -msgstr "Virheelliset palveluargumentit: %s" - -#: VirtualMailManager/cli/subcommands.py:426 -msgid "Missing domain name and new transport." -msgstr "Puuttuva verkkotunnusnimi ja uusi siirto." - -#: VirtualMailManager/cli/subcommands.py:429 -msgid "Missing new transport." -msgstr "Puuttuva uusi siirto." - -#: VirtualMailManager/cli/subcommands.py:455 -msgid "Missing UID." -msgstr "Puuttuva käyttäjätunniste." - -#: VirtualMailManager/cli/subcommands.py:456 -#: VirtualMailManager/cli/subcommands.py:653 -#: VirtualMailManager/cli/subcommands.py:661 -msgid "Account" -msgstr "Tilit" - -#: VirtualMailManager/cli/subcommands.py:471 -#, python-format -msgid "Unknown help topic: '%s'" -msgstr "Tuntematon opasteaihe: ’%s’" - -#: VirtualMailManager/cli/subcommands.py:484 -msgid "List of available subcommands:" -msgstr "Käytettävissä olevien alikomentojen luettelo:" - -#: VirtualMailManager/cli/subcommands.py:507 -msgid "Usable encoding suffixes:" -msgstr "Käyttökelpoiset koodausloppuliitteet:" - -#: VirtualMailManager/cli/subcommands.py:507 -msgid "Usable password schemes:" -msgstr "Käyttökelpoiset salasanakaavat:" - -#: VirtualMailManager/cli/subcommands.py:557 -msgid "Missing relocated address and destination." -msgstr "Puuttuva sijoitusosoite ja -kohde." - -#: VirtualMailManager/cli/subcommands.py:566 -#: VirtualMailManager/cli/subcommands.py:573 -msgid "Missing relocated address." -msgstr "Puuttuva sijoitusosoite." - -#: VirtualMailManager/cli/subcommands.py:596 -#: VirtualMailManager/cli/subcommands.py:609 -#: VirtualMailManager/cli/subcommands.py:622 -#: VirtualMailManager/cli/subcommands.py:680 -#: VirtualMailManager/cli/subcommands.py:691 -#: VirtualMailManager/cli/subcommands.py:730 -msgid "Missing e-mail address." -msgstr "Puuttuva sähköpostiosoite." - -#: VirtualMailManager/cli/subcommands.py:603 -#, python-format -msgid "Generated password: %s" -msgstr "Tuotettu salasana: %s" - -#: VirtualMailManager/cli/subcommands.py:662 -msgid "alias addresses" -msgstr "aliasosoitteet" - -#: VirtualMailManager/cli/subcommands.py:668 -msgid "Missing e-mail address and user's name." -msgstr "Puuttuva sähköpostiosoite ja käyttäjän nimi." - -#: VirtualMailManager/cli/subcommands.py:703 -msgid "Missing e-mail address and storage value." -msgstr "Puuttuva sähköpostiosoite ja käyttäjän nimi." - -#: VirtualMailManager/cli/subcommands.py:744 -msgid "Missing e-mail address and transport." -msgstr "Puuttuva sähköpostiosoite ja siirto." - -#: VirtualMailManager/cli/subcommands.py:747 -msgid "Missing transport." -msgstr "Puuttuva siirto." - -#: VirtualMailManager/cli/subcommands.py:757 -msgid "usage: " -msgstr "käyttö: " - -#. TP: Please adjust translated words like the original text. -#. (It's a table header.) Extract from usage text: -#. usage: vmm subcommand arguments -#. short long -#. subcommand arguments -#. -#. da domainadd fqdn [transport] -#. dd domaindelete fqdn [force] -#: VirtualMailManager/cli/subcommands.py:767 -#, python-format -msgid "" -"usage: %s subcommand arguments\n" -" short long\n" -" subcommand arguments\n" -msgstr "" -"käyttö: %s alikomento argumentit\n" -" lyhyt pitkä\n" -" alikomento argumentit\n" - -#: VirtualMailManager/cli/subcommands.py:786 -msgid "from" -msgstr "kohteesta" - -#. TP: The words 'from', 'version' and 'on' are used in -#. the version information, e.g.: -#. vmm, version 0.5.2 (from 09/09/09) -#. Python 2.5.4 on FreeBSD -#: VirtualMailManager/cli/subcommands.py:786 -msgid "version" -msgstr "versio" - -#: VirtualMailManager/cli/subcommands.py:789 -msgid "on" -msgstr "kohteessa" - -#: VirtualMailManager/cli/subcommands.py:791 -msgid "is free software and comes with ABSOLUTELY NO WARRANTY." -msgstr "on vapaa ohjelmisto ja tulee EHDOTTOMASTI ILMAN TAKUUTA." - -#: VirtualMailManager/cli/subcommands.py:800 -msgid "get the address of the user with the given UID" -msgstr "hae käyttäjän osoite annetulla käyttäjätunnuksella" - -#: VirtualMailManager/cli/subcommands.py:802 -msgid "create a new e-mail user with the given address" -msgstr "luo uusi sähköpostikäyttäj annetulla osoitteella" - -#: VirtualMailManager/cli/subcommands.py:804 -msgid "delete the specified user" -msgstr "poista määritelty käyttäjä" - -#: VirtualMailManager/cli/subcommands.py:806 -msgid "display information about the given address" -msgstr "näytä tietoja annetusta osoitteesta" - -#: VirtualMailManager/cli/subcommands.py:808 -msgid "set, update or delete the real name for an address" -msgstr "aseta, päivitä tai poista osoitteen todellinen nimi" - -#: VirtualMailManager/cli/subcommands.py:811 -msgid "update the password for the given address" -msgstr "päivitä annetun osoitteen salasana" - -#: VirtualMailManager/cli/subcommands.py:814 -msgid "update the quota limit for the given address" -msgstr "päivitä annetun osoitteen kiintiöraja" - -#: VirtualMailManager/cli/subcommands.py:817 -msgid "enables the specified services and disables all not specified services" -msgstr "ottaa käyttöön määritellyt palvelut ja ottaa pois käytöstä määrittelemättömät palvelut" - -#: VirtualMailManager/cli/subcommands.py:821 -msgid "update the transport of the given address" -msgstr "päivitä annetun osoitteen siirto" - -#: VirtualMailManager/cli/subcommands.py:823 -msgid "set, update or delete the note of the given address" -msgstr "aseta, päivitä tai poista annetun osoitteen muistiinpano" - -#: VirtualMailManager/cli/subcommands.py:826 -msgid "create a new alias e-mail address with one or more destinations" -msgstr "luo uusi aliassähköpostiosoite yhdellä tai useammalla kohteella" - -#: VirtualMailManager/cli/subcommands.py:830 -msgid "delete the specified alias e-mail address or one of its destinations" -msgstr "poista määritellyn aliaksen sähköpostiosoite tai yksi sen kohteista" - -#: VirtualMailManager/cli/subcommands.py:833 -msgid "show the destination(s) of the specified alias" -msgstr "näytä määritellyn aliaksen kohteet" - -#: VirtualMailManager/cli/subcommands.py:837 -msgid "create a new alias for an existing domain" -msgstr "luotu uusi alias olemassaolevaan verkkotunnukseen" - -#: VirtualMailManager/cli/subcommands.py:839 -msgid "delete the specified alias domain" -msgstr "poista määritelty aliasverkkotunnus" - -#: VirtualMailManager/cli/subcommands.py:841 -msgid "show the destination of the given alias domain" -msgstr "näytä annetun aliasverkkotunnuksen kohde" - -#: VirtualMailManager/cli/subcommands.py:843 -msgid "assign the given alias domain to an other domain" -msgstr "liitä annettu aliasverkkotunnus toiseen verkkotunnukseen" - -#: VirtualMailManager/cli/subcommands.py:848 -msgid "add one or more catch-all destinations for a domain" -msgstr "lisää yksi tai useampi sieppaa-kaikki-kohde verkkotunnukselle" - -#: VirtualMailManager/cli/subcommands.py:852 -msgid "delete the specified catch-all destination or all of a domain's destinations" -msgstr "poista määritelty sieppaa-kaikki-kohde tai kaikki verkkotunnuksen kohteet" - -#: VirtualMailManager/cli/subcommands.py:855 -msgid "show the catch-all destination(s) of the specified domain" -msgstr "näytä määritellyn aliaksen sieppaa-kaikki-kohteet" - -#: VirtualMailManager/cli/subcommands.py:859 -msgid "create a new domain" -msgstr "luo uusi verkkotunnus" - -#: VirtualMailManager/cli/subcommands.py:861 -msgid "delete the given domain and all its alias domains" -msgstr "poista annettu verkkotunnus ja kaikki sen aliasverkkotunnukset" - -#: VirtualMailManager/cli/subcommands.py:863 -msgid "display information about the given domain" -msgstr "näytä tiedot annetusta verkkotunnuksesta" - -#: VirtualMailManager/cli/subcommands.py:866 -msgid "update the quota limit of the specified domain" -msgstr "päivitä määritellyn verkkotunnuksen kiintiöraja" - -#: VirtualMailManager/cli/subcommands.py:869 -msgid "enables the specified services and disables all not specified services of the given domain" -msgstr "ottaa käyttöön määritellyt palvelut ja ottaa pois käytöstä kaikki määrittelemättömät annetun verkkotunnuksen palvelut" - -#: VirtualMailManager/cli/subcommands.py:873 -msgid "update the transport of the specified domain" -msgstr "päivitä määritellyn verkkotunnuksen siirto" - -#: VirtualMailManager/cli/subcommands.py:875 -msgid "set, update or delete the note of the given domain" -msgstr "aseta, päivitä tai poista määritellyn verkkotunnuksen muistiinpano" - -#: VirtualMailManager/cli/subcommands.py:878 -msgid "list all domains or search for domains by pattern" -msgstr "luettele kaikki mallin mukaiset verkkotunnukset / verkkotunnushaut" - -#: VirtualMailManager/cli/subcommands.py:880 -msgid "list all addresses or search for addresses by pattern" -msgstr "luettele kaikki mallin mukaiset osoitteet / osoitehaut" - -#: VirtualMailManager/cli/subcommands.py:883 -msgid "list all user accounts or search for accounts by pattern" -msgstr "luettele kaikki mallin mukaiset käyttäjätilit / tilihaut" - -#: VirtualMailManager/cli/subcommands.py:886 -msgid "list all aliases or search for aliases by pattern" -msgstr "luettele kaikki mallin mukaiset aliakset / aliashaut" - -#: VirtualMailManager/cli/subcommands.py:888 -msgid "list all relocated users or search for relocated users by pattern" -msgstr "luettele kaikki mallin mukaiset sijoitetut käyttäjät / sijoitettujen käyttäjien haut" - -#: VirtualMailManager/cli/subcommands.py:893 -msgid "create a new record for a relocated user" -msgstr "luo uusi tietue sijoitettavalle käyttäjälle" - -#: VirtualMailManager/cli/subcommands.py:896 -msgid "delete the record of the relocated user" -msgstr "poista sijoitetun käyttäjän tietue" - -#: VirtualMailManager/cli/subcommands.py:898 -msgid "print information about a relocated user" -msgstr "tulosta tiedot sijoitetusta käyttäjästä" - -#: VirtualMailManager/cli/subcommands.py:901 -msgid "show the actual value of the configuration option" -msgstr "näytä asetusvalitsimen todellinen arvo" - -#: VirtualMailManager/cli/subcommands.py:903 -msgid "set a new value for the configuration option" -msgstr "aseta asetusvalitsimelle uusi arvo" - -#: VirtualMailManager/cli/subcommands.py:905 -msgid "start interactive configuration mode" -msgstr "aloita vuorovaikutteinen asetustila" - -#: VirtualMailManager/cli/subcommands.py:907 -msgid "lists all usable password schemes and password encoding suffixes" -msgstr "luettelee kaikki käytettävät salasanakaavat ja salasanakoodausloppuliitteet" - -#: VirtualMailManager/cli/subcommands.py:910 -msgid "show a help overview or help for the given subcommand" -msgstr "näytä opasteyhteenveto tai opaste annetusta alikomennosta" - -#: VirtualMailManager/cli/subcommands.py:912 -msgid "show version and copyright information" -msgstr "näytä versio ja copyright-tiedot" - -#. TP: e.g.: [ 0.00%] 21.09 KiB/1.00 GiB -#: VirtualMailManager/cli/subcommands.py:968 -#, python-format -msgid "[%(percent)s%%] %(used)s/%(limit)s" -msgstr "[%(percent)s%%] %(used)s/%(limit)s" - -#. TP: used in e.g. 'Domain information' or 'Account information' -#: VirtualMailManager/cli/subcommands.py:974 -msgid "information" -msgstr "tiedot" - -#: VirtualMailManager/cli/subcommands.py:988 -msgid "Note" -msgstr "Muistiinpano" - -#. TP: used in e.g. 'Existing alias addresses' or 'Existing accounts' -#: VirtualMailManager/cli/subcommands.py:1004 -msgid "Existing" -msgstr "Olemassa oleva" - -#: VirtualMailManager/cli/subcommands.py:1017 -#: VirtualMailManager/cli/subcommands.py:1069 -#: VirtualMailManager/cli/subcommands.py:1113 -msgid "\tNone" -msgstr "\tEi mitään" - -#: VirtualMailManager/cli/subcommands.py:1022 -msgid "Alias information" -msgstr "Aliastiedot" - -#: VirtualMailManager/cli/subcommands.py:1024 -#, python-format -msgid "\tMail for %s will be redirected to:" -msgstr "\tSähköposti %s ohjataan edelleen osoitteeseen:" - -#: VirtualMailManager/cli/subcommands.py:1031 -msgid "Catch-all information" -msgstr "Sieppaa-kaikki-tiedot" - -#: VirtualMailManager/cli/subcommands.py:1033 -#, python-format -msgid "\tMail to unknown local-parts in domain %s will be sent to:" -msgstr "\tSähköposti tuntemattomaan paikallisosaan verkkotunnuksessa %s lähetetään osoitteeseen:" - -#: VirtualMailManager/cli/subcommands.py:1041 -msgid "Relocated information" -msgstr "Sijaintitiedot" - -# Alla "addr" ja "dest" ovat muuttujia, jotka korvautuvat suorituksen yhteydessä koodilla. -#: VirtualMailManager/cli/subcommands.py:1043 -#, python-format -msgid "\tUser '%(addr)s' has moved to '%(dest)s'" -msgstr "\tKäyttäjä ’%(addr)s’ on siirretty kohteeseen ’%(dest)s’" - -#: VirtualMailManager/cli/subcommands.py:1058 -msgid "Matching domains" -msgstr "Täsmäävät verkkotunnukset" - -#: VirtualMailManager/cli/subcommands.py:1060 -msgid "Existing domains" -msgstr "Olemassaolevat verkkotunnukset" - -#: VirtualMailManager/cli/subcommands.py:1076 -msgid "user accounts" -msgstr "käyttäjätilit" - -#: VirtualMailManager/cli/subcommands.py:1079 -msgid "user accounts and aliases" -msgstr "käyttäjätilit ja aliakset" - -#: VirtualMailManager/cli/subcommands.py:1080 -msgid "user accounts and relocated users" -msgstr "käyttäjätilit ja sijoitetut käyttäjät" - -#: VirtualMailManager/cli/subcommands.py:1081 -msgid "aliases and relocated users" -msgstr "aliakset ja sijoitetut käyttäjät" - -#: VirtualMailManager/cli/subcommands.py:1082 -msgid "addresses" -msgstr "osoitteet" - -#: VirtualMailManager/cli/subcommands.py:1086 -#, python-format -msgid "Matching %s" -msgstr "Täsmäävät %s" - -#: VirtualMailManager/cli/subcommands.py:1088 -#, python-format -msgid "Existing %s" -msgstr "Olemassa oleva %s" - -#: VirtualMailManager/cli/subcommands.py:1091 -#, python-format -msgid "Invalid address type for list: '%s'" -msgstr "Virheellinen osoitetyyppi luettelolle: ’%s’" - -#. TP: the letters 'u', 'a' and 'r' are abbreviations of user, -#. alias and relocated user -#: VirtualMailManager/cli/subcommands.py:1101 -msgid "u" -msgstr "u" - -#: VirtualMailManager/cli/subcommands.py:1102 -msgid "a" -msgstr "a" - -#: VirtualMailManager/cli/subcommands.py:1103 -msgid "r" -msgstr "r" - -#: VirtualMailManager/cli/subcommands.py:1119 -msgid "Alias domain information" -msgstr "Aliasverkkotunnustiedot" - -# Alla "alias" ja "domain" ovat muuttujia, jotka korvautuvat suorituksen yhteydessä koodilla. -#: VirtualMailManager/cli/subcommands.py:1124 -#, python-format -msgid "" -"\tThe alias domain %(alias)s belongs to:\n" -"\t * %(domain)s" -msgstr "" -"\tAliasverkkotunnus %(alias)s kuuluu kohteeseen:\n" -"\t * %(domain)s" - -#: VirtualMailManager/common.py:63 -#, python-format -msgid "No such file: '%s'" -msgstr "Ei löydy tiedostoa: ’%s’" - -#: VirtualMailManager/common.py:66 -#, python-format -msgid "File is not executable: '%s'" -msgstr "Tiedosto ei ole suoritettava tiedosto: ’%s’" - -#: VirtualMailManager/common.py:83 -msgid "GiB" -msgstr "gibitavua" - -#. TP: abbreviations of gibibyte, tebibyte kibibyte and mebibyte -#: VirtualMailManager/common.py:83 -msgid "TiB" -msgstr "tebitavua" - -#: VirtualMailManager/common.py:84 -msgid "KiB" -msgstr "kibitavua" - -#: VirtualMailManager/common.py:84 -msgid "MiB" -msgstr "mebitavua" - -#. TP: e.g.: '%(size)s %(prefix)s' -> '118.30 MiB' -#: VirtualMailManager/common.py:88 -#, python-format -msgid "%(size)s %(prefix)s" -msgstr "%(size)s %(prefix)s" - -#: VirtualMailManager/common.py:139 -#, python-format -msgid "Invalid transport '%(transport)s' for mailbox format '%(mbfmt)s'." -msgstr "Virheellinen siirto ’%(transport)s’ sähköpostilaatikkomuodolle ’%(mbfmt)s’." - -#. TP: [domain default] indicates that a user's setting is the same as -#. configured in the user's domain. -#. e.g.: [ 0.84%] 42/5,000 [domain default] -#: VirtualMailManager/common.py:217 -#, python-format -msgid "%s [domain default]" -msgstr "%s [verkkotunnusoletus]" - -#: VirtualMailManager/config.py:89 -#, python-format -msgid "Not a boolean: '%s'" -msgstr "Ei ole boolean-arvo: ’%s’" - -#: VirtualMailManager/config.py:127 -#, python-format -msgid "Bad format: '%s' - expected: section.option" -msgstr "Väärä muoto: ’%s’ - odotettiin: lohko.valitsin" - -#: VirtualMailManager/config.py:378 -#, python-format -msgid "* Section: %s\n" -msgstr "* Lohko: %s\n" - -#: VirtualMailManager/config.py:388 VirtualMailManager/config.py:396 -#, python-format -msgid "Check of configuration file %s failed.\n" -msgstr "Asetustiedoston %s tarkistus epäonnistui.\n" - -#: VirtualMailManager/config.py:390 -msgid "Missing options, which have no default value.\n" -msgstr "Puuttuu valitsimia, joilla ei ole oletusarvoa.\n" - -#: VirtualMailManager/config.py:398 VirtualMailManager/config.py:400 -msgid "Invalid configuration values.\n" -msgstr "Virheelliset asetusarvot.\n" - -#: VirtualMailManager/config.py:439 VirtualMailManager/config.py:523 -#, python-format -msgid "Not a valid Dovecot version: '%s'" -msgstr "Ei ole kelvollinen Dovecot-versio: ’%s’" - -#: VirtualMailManager/config.py:445 VirtualMailManager/config.py:480 -#, python-format -msgid "Unsupported database module: '%s'" -msgstr "Tukematon tietokantamoduuli: ’%s’" - -#: VirtualMailManager/config.py:450 VirtualMailManager/config.py:488 -#, python-format -msgid "Unknown pgsql SSL mode: '%s'" -msgstr "Tuntematon pgsql SSL -tila: ’%s’" - -#: VirtualMailManager/config.py:457 VirtualMailManager/config.py:501 -#: VirtualMailManager/maillocation.py:70 -#, python-format -msgid "Unsupported mailbox format: '%s'" -msgstr "Tukematon sähköpostilaatikkomuoto: ’%s’" - -# Tässä argumentti saattaa olla hakemistonimi tai sitten virheilmoitus. -#: VirtualMailManager/config.py:473 VirtualMailManager/handler.py:287 -#: VirtualMailManager/handler.py:363 VirtualMailManager/handler.py:368 -#: VirtualMailManager/handler.py:396 -#, python-format -msgid "No such directory: %s" -msgstr "Ei löydy hakemistoa: %s" - -#: VirtualMailManager/config.py:512 -#, python-format -msgid "Not a valid size value: '%s'" -msgstr "Ei ole kelvollinen kokoarvo: ’%s’" - -#: VirtualMailManager/domain.py:84 -#, python-format -msgid "The domain '%s' is an alias domain." -msgstr "Verkkotunnus ’%s’ on aliasverkkotunnus." - -#: VirtualMailManager/domain.py:119 -#, python-format -msgid "There are %(account_count)u accounts, %(alias_count)u aliases and %(relocated_count)u relocated users." -msgstr "On %(account_count)u -tiliä, %(alias_count)u -aliasta ja %(relocated_count)u sijoitettua käyttäjää." - -#: VirtualMailManager/domain.py:134 -#, python-format -msgid "The domain '%s' already exists." -msgstr "Verkkotunnus ’%s’ on jo olemassa." - -#: VirtualMailManager/domain.py:507 -msgid "The domain name is too long" -msgstr "Verkkotunnusnimi on liian pitkä" - -#: VirtualMailManager/domain.py:509 -#, python-format -msgid "The domain name '%s' is invalid" -msgstr "Verkkotunnusnimi ’%s’ on virheellinen" - -#: VirtualMailManager/emailaddress.py:73 -#, python-format -msgid "Missing the '@' sign in address: '%s'" -msgstr "Merkki ’@’ puuttuu sähköpostiosoitteesta: ’%s’." - -#: VirtualMailManager/emailaddress.py:76 -#, python-format -msgid "Too many '@' signs in address: '%s'" -msgstr "Liian monta ’@’-merkkiä sähköpostiosoitteessa: ’%s’." - -#: VirtualMailManager/emailaddress.py:79 -#, python-format -msgid "Missing local-part in address: '%s'" -msgstr "Puuttuu paikallisosa osoitteessa: ’%s’" - -#: VirtualMailManager/emailaddress.py:82 -#, python-format -msgid "Missing domain name in address: '%s'" -msgstr "Puuttuu verkkotunnusnimi osoitteessa: ’%s’" - -#: VirtualMailManager/emailaddress.py:145 -#, python-format -msgid "The local-part '%s' is too long." -msgstr "Paikallisosa ’%s’ on liian pitkä." - -# Alla "l_part" ja "i_chars" ovat muuttujia, jotka korvautuvat suorituksen yhteydessä koodilla. -#: VirtualMailManager/emailaddress.py:150 -#, python-format -msgid "The local-part '%(l_part)s' contains invalid characters: %(i_chars)s" -msgstr "Paikallisosa ’%(l_part)s’ sisältää virheellisiä merkkejä: %(i_chars)s" - -#: VirtualMailManager/ext/postconf.py:84 -#, python-format -msgid "The value '%s' does not look like a valid Postfix configuration parameter name." -msgstr "Arvo ’%s’ ei näytä olevan kelvollinen Postfix-asetusparametrinimi." - -#: VirtualMailManager/handler.py:54 -msgid "an account" -msgstr "tili" - -#: VirtualMailManager/handler.py:55 -msgid "an alias" -msgstr "alias" - -#: VirtualMailManager/handler.py:56 -msgid "a relocated user" -msgstr "sijoitettu käyttäjä" - -#: VirtualMailManager/handler.py:82 -msgid "" -"You are not root.\n" -"\tGood bye!\n" -msgstr "" -"Et ole root-käyttäjä.\n" -"\tNäkemiin!\n" - -#: VirtualMailManager/handler.py:102 -#, python-format -msgid "Could not find '%(cfg_file)s' in: '%(cfg_path)s'" -msgstr "Ei voitu löytää ’%(cfg_file)s’ kohteessa: ’%(cfg_path)s’" - -# Alla "perms" ja "file" ovat muuttujia, jotka korvautuvat suorituksen yhteydessä koodilla. Lainausmerkit jätettiin paikallistamatta, koska ne saattavat olla skriptin toiminnan kannalta kriittisiä. -#. TP: Please keep the backticks around the command. `chmod 0600 …` -#: VirtualMailManager/handler.py:114 -#, python-format -msgid "" -"wrong permissions for '%(file)s': %(perms)s\n" -"`chmod 0600 %(file)s` would be great." -msgstr "" -"korjaa käyttöoikeudet tiedostolle ’%(file)s’: %(perms)s\n" -"’chmod 0600 %(file)s’ olisi erinomainen." - -#: VirtualMailManager/handler.py:134 -#, python-format -msgid "" -"'%(path)s' is not a directory.\n" -"(%(cfg_file)s: section 'misc', option 'base_directory')" -msgstr "" -"’%(path)s’ ei ole hakemisto.\n" -"(%(cfg_file)s: lohko ’misc’, valitsin ’base_directory’)" - -#: VirtualMailManager/handler.py:143 -#, python-format -msgid "" -"\n" -"(%(cfg_file)s: section 'bin', option '%(option)s')" -msgstr "" -"\n" -"(%(cfg_file)s: lohko ’bin’, valitsin ’%(option)s’)" - -#: VirtualMailManager/handler.py:157 VirtualMailManager/handler.py:164 -#, python-format -msgid "Unable to import database module '%s'." -msgstr "Tietokantamoduulin ’%s’ tuominen epäonnistui." - -#. TP: %(a_type)s will be one of: 'an account', 'an alias' or -#. 'a relocated user' -#: VirtualMailManager/handler.py:243 -#, python-format -msgid "There is already %(a_type)s with the address '%(address)s'." -msgstr "On jo %(a_type)s osoitteessa ’%(address)s’." - -#: VirtualMailManager/handler.py:302 -#, python-format -msgid "'%s' is not a directory." -msgstr "’%s’ ei ole hakemisto." - -#: VirtualMailManager/handler.py:305 -#, python-format -msgid "The file/directory '%s' already exists." -msgstr "Tiedosto/hakemisto ’%s’ on jo olemassa." - -#: VirtualMailManager/handler.py:335 -msgid "Skipped mailbox folders:" -msgstr "Ohitettiin sähköpostilaatikkokansiot:" - -#: VirtualMailManager/handler.py:355 -#, python-format -msgid "UID '%(uid)u' and/or GID '%(gid)u' are less than %(min_uid)u/%(min_gid)u." -msgstr "Käyttäjätunniste ’%(uid)u’ ja/tai käyttäjätunniste ’%(gid)u’ ovat pienempiä kuin %(min_uid)u/%(min_gid)u." - -#: VirtualMailManager/handler.py:360 VirtualMailManager/handler.py:393 -#, python-format -msgid "Found \"..\" in domain directory path: %s" -msgstr "Löytyi ”..” verkkotunnuksen hakemistopolussa: %s" - -#: VirtualMailManager/handler.py:373 -msgid "Detected owner/group mismatch in home directory." -msgstr "Havaittu omistaja-/ryhmätäsmäämättömyys kotihakemistossa." - -#: VirtualMailManager/handler.py:389 -#, python-format -msgid "GID '%(gid)u' is less than '%(min_gid)u'." -msgstr "Käyttäjätunniste ’%(gid)u’ on pienempi kuin ’%(min_gid)u’." - -#: VirtualMailManager/handler.py:400 -#, python-format -msgid "Detected group mismatch in domain directory: %s" -msgstr "Havaittu ryhmätäsmäämättömyys verkkotunnushakemistossa: %s" - -#: VirtualMailManager/handler.py:476 VirtualMailManager/handler.py:878 -#, python-format -msgid "Unknown service: '%s'" -msgstr "Tuntematon palvelu: ’%s’" - -#: VirtualMailManager/handler.py:601 VirtualMailManager/handler.py:625 -#: VirtualMailManager/handler.py:639 -#, python-format -msgid "The pattern '%s' contains invalid characters." -msgstr "Säännöllinen lauseke ’%s’ sisältää virheellisiä merkkejä." - -#: VirtualMailManager/handler.py:669 VirtualMailManager/handler.py:732 -#: VirtualMailManager/handler.py:746 VirtualMailManager/handler.py:776 -msgid "Ignored destination addresses:" -msgstr "Ohitetut kohdeosoitteet:" - -#: VirtualMailManager/handler.py:674 VirtualMailManager/handler.py:751 -#: VirtualMailManager/handler.py:895 -#, python-format -msgid "The destination account/alias '%s' does not exist." -msgstr "Kohdetili/-alias ’%s’ ei ole olemassa." - -# Alla "directory" ja "reason" ovat muuttujia, jotka korvautuvat suorituksen yhteydessä koodilla. -#: VirtualMailManager/handler.py:696 -#, python-format -msgid "" -"The account has been successfully deleted from the database.\n" -" But an error occurred while deleting the following directory:\n" -" '%(directory)s'\n" -" Reason: %(reason)s" -msgstr "" -"Tili on poistettu onnistuneesti tietokannasta.\n" -" Mutta tapahtui virhe, kun poistettiin seuraavaa hakemistoa:\n" -" ’%(directory)s’\n" -" Syy: %(reason)s" - -#: VirtualMailManager/handler.py:854 -#, python-format -msgid "Could not accept transport: '%s'" -msgstr "Siirron hyväksyminen epäonnistui: ’%s’" - -#: VirtualMailManager/handler.py:905 VirtualMailManager/relocated.py:106 -#: VirtualMailManager/relocated.py:113 -#, python-format -msgid "The relocated user '%s' does not exist." -msgstr "Sijoitettua käyttäjää ’%s’ ei ole olemassa." - -#: VirtualMailManager/mailbox.py:260 -#, python-format -msgid "Failed to create mailboxes: %r\n" -msgstr "Sähköpostilaatikoiden luominen epäonnistui: %r\n" - -#: VirtualMailManager/maillocation.py:74 -msgid "Empty directory name" -msgstr "Tyhjä hakemistonimi" - -#: VirtualMailManager/maillocation.py:76 -#, python-format -msgid "Directory name is too long: '%s'" -msgstr "Verkkotunnusnimi on liian pitkä: ’%s’" - -#: VirtualMailManager/password.py:389 -#, python-format -msgid "Unsupported password scheme: '%s'" -msgstr "Tukematon salasanakaava: ’%s’" - -#: VirtualMailManager/password.py:392 -#, python-format -msgid "The password scheme '%(scheme)s' requires Dovecot >= v%(version)s." -msgstr "Salasanakaava ’%(scheme)s’ vaatii Dovecot >= v%(version)s." - -#: VirtualMailManager/password.py:398 -msgid "Encoding suffixes for password schemes require Dovecot >= v1.1.alpha1." -msgstr "Koodausloppuliitteet salasanakaavoille vaativat Dovecot >= v1.1.alpha1." - -#: VirtualMailManager/password.py:401 -#, python-format -msgid "Unsupported password encoding: '%s'" -msgstr "Tukematon salasanakoodaus: ’%s’" - -#: VirtualMailManager/relocated.py:62 VirtualMailManager/relocated.py:76 -msgid "The destination address' domain name must not be localhost." -msgstr "Kohdeosoitteen verkkotunnusnimi ei saa olla localhost." - -#: VirtualMailManager/relocated.py:79 -msgid "Address and destination are identical." -msgstr "Osoite ja kohde ovat identtisiä." - -#: VirtualMailManager/relocated.py:83 -#, python-format -msgid "The relocated user '%s' already exists." -msgstr "Sijoitettu käyttäjä ’%s’ on jo olemassa." - -#~ msgid "The address '%(addr)s' is not a destination of the alias '%(alias)s'." -#~ msgstr "Osoite ’%(addr)s’ ei ole aliaksen ’%(alias)s’ kohde." - -#~ msgid "Missing user's name." -#~ msgstr "Puuttuva käyttäjän nimi." - -#~ msgid "uid" -#~ msgstr "käyttäjätunniste" - -#~ msgid "address [password]" -#~ msgstr "osoite [salasana]" - -#~ msgid "address [details]" -#~ msgstr "osoite [yksityiskohdat]" - -#~ msgid "address name" -#~ msgstr "osoitenimi" - -#~ msgid "address storage [messages]" -#~ msgstr "osoitetallennus [viestit]" - -#~ msgid "address [service ...]" -#~ msgstr "osoite [palvelu ...]" - -#~ msgid "address transport" -#~ msgstr "osoitesiirto" - -#~ msgid "address destination ..." -#~ msgstr "osoitekohde ..." - -#~ msgid "address [destination]" -#~ msgstr "osoite [kohde]" - -#~ msgid "fqdn" -#~ msgstr "fqdn" - -#~ msgid "fqdn [transport]" -#~ msgstr "fqdn [siirto]" - -#~ msgid "fqdn [details]" -#~ msgstr "fqdn [yksityiskohdat]" - -#~ msgid "fqdn storage [messages]" -#~ msgstr "fqdn-tallennus [viestit]" - -#~ msgid "fqdn [service ...]" -#~ msgstr "fqdn [palvelu ...]" - -#~ msgid "fqdn transport" -#~ msgstr "fqdn-siirto" - -#~ msgid "[pattern]" -#~ msgstr "[malli]" - -#~ msgid "address newaddress" -#~ msgstr "osoite newaddress" - -#~ msgid "option" -#~ msgstr "valitsin" - -#~ msgid "option value" -#~ msgstr "valitsinarvo" - -#~ msgid "[section]" -#~ msgstr "[lohko]" - -#~ msgid "[subcommand]" -#~ msgstr "[alikomento]" - -#~ msgid "Could not accept name: '%s'" -#~ msgstr "Ei voitu hyväksyä nimeä: ’%s’" - -#~ msgid "There is already a relocated user with the address “%s”." -#~ msgstr "On jo sijoitettu käyttäjä osoitteella “%s”." - -#~ msgid "There is already an account with address “%s”." -#~ msgstr "On jo olemassa tili osoitteella “%s”." diff -r 659c4476c57c -r b678a1c43027 po/fr.po --- a/po/fr.po Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1291 +0,0 @@ -# traduction française -# This file is distributed under the same license as the vmm package. -# Copyright (C) 2009 Free Software Foundation, Inc. -# Dimitri Duc <dimitri.duc@gmail.com>, 2009. -msgid "" -msgstr "" -"Project-Id-Version: vmm 0.6.0\n" -"Report-Msgid-Bugs-To: user+vmm/tp@localhost.localdomain.org\n" -"POT-Creation-Date: 2011-11-07 05:20+0100\n" -"PO-Revision-Date: 2012-01-01 14:59+0100\n" -"Last-Translator: Dimitri Duc <dimitri.duc@gmail.com>\n" -"Language-Team: French <traduc@traduc.org>\n" -"Language: fr\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Language: French\n" -"X-Poedit-Country: FRANCE\n" - -#. TP: Hm, what “quotation marks” should be used? -#. If you are unsure have a look at: -#. http://en.wikipedia.org/wiki/Quotation_mark,_non-English_usage -#: VirtualMailManager/account.py:58 VirtualMailManager/alias.py:35 -#: VirtualMailManager/domain.py:120 VirtualMailManager/relocated.py:38 -#, fuzzy, python-format -msgid "The domain '%s' does not exist." -msgstr "Le domaine “%s” n'existe pas encore." - -#: VirtualMailManager/account.py:106 -#, python-format -msgid "The mailbox format '%(mbfmt)s' requires Dovecot >= v%(version)s." -msgstr "" - -#: VirtualMailManager/account.py:113 VirtualMailManager/account.py:305 -#, python-format -msgid "Invalid transport '%(transport)s' for mailbox format '%(mbfmt)s'." -msgstr "" - -#: VirtualMailManager/account.py:153 VirtualMailManager/cli/handler.py:93 -#: VirtualMailManager/handler.py:628 VirtualMailManager/handler.py:679 -#: VirtualMailManager/handler.py:705 VirtualMailManager/handler.py:716 -#: VirtualMailManager/handler.py:727 VirtualMailManager/handler.py:739 -#: VirtualMailManager/handler.py:753 -#, fuzzy, python-format -msgid "The account '%s' does not exist." -msgstr "Le compte “%s” n'existe pas." - -#: VirtualMailManager/account.py:204 VirtualMailManager/account.py:214 -#: VirtualMailManager/cli/handler.py:77 VirtualMailManager/handler.py:596 -#, fuzzy, python-format -msgid "The account '%s' already exists." -msgstr "Le compte “%s” existe déjà." - -#: VirtualMailManager/account.py:207 VirtualMailManager/handler.py:701 -#, python-format -msgid "Could not accept password: '%s'" -msgstr "" - -#: VirtualMailManager/account.py:217 -#, python-format -msgid "No password set for account: '%s'" -msgstr "" - -#: VirtualMailManager/account.py:245 -#, python-format -msgid "Unknown field: '%s'" -msgstr "" - -#: VirtualMailManager/account.py:267 VirtualMailManager/domain.py:292 -msgid "PostgreSQL-based dictionary quota requires Dovecot >= v1.1.2." -msgstr "" - -#. TP: A service (e.g. pop3 or imap) may be enabled/usable or -#. disabled/unusable for a user. -#: VirtualMailManager/account.py:332 -msgid "disabled" -msgstr "désactiver" - -#: VirtualMailManager/account.py:332 -msgid "enabled" -msgstr "activer" - -#: VirtualMailManager/account.py:343 -#, python-format -msgid "Could not fetch information for account: '%s'" -msgstr "" - -#: VirtualMailManager/account.py:387 -#, fuzzy, python-format -msgid "There are %(count)d aliases with the destination address '%(address)s'." -msgstr "Il y a %(count)d alias ayant comme adresse de destination “%(address)s”." - -#: VirtualMailManager/account.py:416 -#, fuzzy -msgid "UID must be an int/long." -msgstr "L'identifiant utilisateur doit être de type entier long." - -#: VirtualMailManager/account.py:418 -#, fuzzy -msgid "UID must be greater than 0." -msgstr "L'idenfiant utilisateur doit être plus grand que 0." - -#: VirtualMailManager/account.py:427 -#, fuzzy, python-format -msgid "There is no account with the UID: '%d'" -msgstr "Il n'y a pas de compte avec l'identifiant utilisateur “%d”." - -#: VirtualMailManager/alias.py:60 -#, fuzzy, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"Currently this alias expands into %(count)i/%(limit)i recipients.\n" -"%(count_new)i additional destination(s) will render this alias unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit" -msgstr "" -"Impossible d'ajouter une nouvelle destination à l'alias “%(address)s”.\n" -"Actuellement cet alias s'étend sur %(count)i destinataires.\n" -"Une destination de plus rendra cet alias inutilisable.\n" -"Conseil: Augmenter 'virtual_alias_expansion_limit' dans Postfix\n" - -#: VirtualMailManager/alias.py:67 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"This alias already exceeds its expansion limit (%(count)i/%(limit)i).\n" -"So its unusable, all messages addressed to this alias will be bounced.\n" -"Hint: Delete some destination addresses." -msgstr "" - -#: VirtualMailManager/alias.py:142 VirtualMailManager/alias.py:154 -#: VirtualMailManager/alias.py:161 VirtualMailManager/handler.py:657 -#, fuzzy, python-format -msgid "The alias '%s' does not exist." -msgstr "L'alias “%s” n'existe pas." - -#: VirtualMailManager/alias.py:145 -#, python-format -msgid "The address '%(addr)s' is not a destination of the alias '%(alias)s'." -msgstr "" - -#: VirtualMailManager/aliasdomain.py:50 -#, fuzzy, python-format -msgid "The domain '%s' is a primary domain." -msgstr "Le domaine “%s” est le domaine principale." - -#: VirtualMailManager/aliasdomain.py:69 -#, fuzzy, python-format -msgid "The alias domain '%s' already exists." -msgstr "L'alias de domane “%s” existe déjà." - -#: VirtualMailManager/aliasdomain.py:72 VirtualMailManager/aliasdomain.py:106 -#, fuzzy -msgid "No destination domain set for the alias domain." -msgstr "Pas de destination pour l'alias de domaine relevé." - -#: VirtualMailManager/aliasdomain.py:75 VirtualMailManager/aliasdomain.py:109 -#, fuzzy, python-format -msgid "The target domain '%s' does not exist." -msgstr "La domaine ciblé “%s” n'existe pas encore." - -#: VirtualMailManager/aliasdomain.py:88 VirtualMailManager/aliasdomain.py:112 -#: VirtualMailManager/aliasdomain.py:133 -#, fuzzy, python-format -msgid "The alias domain '%s' does not exist." -msgstr "L'alias de domaine “%s” n'existe pas encore." - -#: VirtualMailManager/aliasdomain.py:98 -#, fuzzy, python-format -msgid "There is no primary domain for the alias domain '%s'." -msgstr "Il n'y a pas de domaine principale pour l'alias de domaine “%s”." - -#: VirtualMailManager/aliasdomain.py:115 -#, fuzzy, python-format -msgid "The alias domain '%(alias)s' is already assigned to the domain '%(domain)s'." -msgstr "L'alias de domaine “%(alias)s” est déjà assigné au domaine “%(domain)s”." - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:78 -msgid "Enter new password: " -msgstr "Entrer un nouveau mot de passe:" - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:80 -msgid "Retype new password: " -msgstr "Re-écrire le mot de passe:" - -#: VirtualMailManager/cli/__init__.py:85 VirtualMailManager/cli/config.py:53 -msgid "Too many failures - try again later." -msgstr "" - -#: VirtualMailManager/cli/__init__.py:91 -#, fuzzy -msgid "Sorry, passwords do not match." -msgstr "Le mot de passe ne correspondent pas" - -#: VirtualMailManager/cli/__init__.py:95 -#, fuzzy -msgid "Sorry, empty passwords are not permitted." -msgstr "Les mots de passe vides ne sont pas autorisées" - -#: VirtualMailManager/cli/config.py:32 -#, fuzzy, python-format -msgid "Enter new value for option %(option)s [%(current_value)s]: " -msgstr "Entrer une nouvelle valeur pour l'option %(opt)s [%(val)s]: " - -#: VirtualMailManager/cli/config.py:36 -#, python-format -msgid "Using configuration file: %s\n" -msgstr "Utilisation du fichier configuration: %s\n" - -#: VirtualMailManager/cli/config.py:38 -#, fuzzy, python-format -msgid "* Configuration section: '%s'" -msgstr "* Configure la section: “%s”" - -#: VirtualMailManager/cli/config.py:50 -#, fuzzy, python-format -msgid "Warning: %s" -msgstr "Avertissements:" - -#: VirtualMailManager/cli/handler.py:66 -#, fuzzy, python-format -msgid "Invalid section: '%s'" -msgstr "Section invalide: “%s”" - -#: VirtualMailManager/cli/main.py:32 VirtualMailManager/cli/main.py:65 -#: VirtualMailManager/cli/main.py:68 VirtualMailManager/cli/subcommands.py:629 -#: VirtualMailManager/cli/subcommands.py:649 -#, fuzzy, python-format -msgid "Error: %s" -msgstr "Erreur" - -#: VirtualMailManager/cli/main.py:41 -msgid "You must specify a subcommand at least." -msgstr "" - -#: VirtualMailManager/cli/main.py:53 -#, fuzzy, python-format -msgid "Unknown subcommand: '%s'" -msgstr "Sous-commande inconue." - -#. TP: We have to cry, because root has killed/interrupted vmm -#. with Ctrl+C or Ctrl+D. -#: VirtualMailManager/cli/main.py:62 -#, fuzzy -msgid "Ouch!" -msgstr "Aie" - -#: VirtualMailManager/cli/main.py:71 -#, python-format -msgid "Error: Unknown section: '%s'" -msgstr "" - -#: VirtualMailManager/cli/main.py:74 -#, python-format -msgid "Error: No option '%(option)s' in section: '%(section)s'" -msgstr "" - -#: VirtualMailManager/cli/main.py:77 -msgid "Warnings:" -msgstr "Avertissements:" - -#: VirtualMailManager/cli/subcommands.py:78 -#, python-format -msgid "Plan A failed ... trying Plan B: %(subcommand)s %(object)s" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:92 -msgid "Missing alias address and destination." -msgstr "Absence de l'adresse alias et de la destination." - -#: VirtualMailManager/cli/subcommands.py:95 -#: VirtualMailManager/cli/subcommands.py:453 -msgid "Missing destination address." -msgstr "Absence de l'adresse destination." - -#: VirtualMailManager/cli/subcommands.py:102 -#: VirtualMailManager/cli/subcommands.py:112 -#, fuzzy -msgid "Missing alias address." -msgstr "Absence de l'adresse alias" - -#: VirtualMailManager/cli/subcommands.py:134 -#: VirtualMailManager/cli/subcommands.py:168 -#, fuzzy -msgid "Missing alias domain name and destination domain name." -msgstr "Absence du nom de l'alias de domaine et du nom cible de domaine" - -#: VirtualMailManager/cli/subcommands.py:137 -#: VirtualMailManager/cli/subcommands.py:171 -#, fuzzy -msgid "Missing destination domain name." -msgstr "Asbence du nom cible de domaine" - -#: VirtualMailManager/cli/subcommands.py:145 -#: VirtualMailManager/cli/subcommands.py:152 -msgid "Missing alias domain name." -msgstr "Absence du nom de l'alias de domaine." - -#: VirtualMailManager/cli/subcommands.py:179 -#, fuzzy -msgid "Missing option name." -msgstr "Absence de nom de domaine." - -#: VirtualMailManager/cli/subcommands.py:195 -#, fuzzy -msgid "Missing option and new value." -msgstr "Absence de nom de domaine et de nouveau transport." - -#: VirtualMailManager/cli/subcommands.py:197 -#, fuzzy -msgid "Missing new configuration value." -msgstr "Utilisation du fichier configuration: %s\n" - -#: VirtualMailManager/cli/subcommands.py:213 -#: VirtualMailManager/cli/subcommands.py:229 -#: VirtualMailManager/cli/subcommands.py:242 -#: VirtualMailManager/cli/subcommands.py:331 -msgid "Missing domain name." -msgstr "Absence de nom de domaine." - -#: VirtualMailManager/cli/subcommands.py:219 -#, python-format -msgid "Creating account for postmaster@%s" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:235 -#: VirtualMailManager/cli/subcommands.py:249 -#: VirtualMailManager/cli/subcommands.py:322 -#: VirtualMailManager/cli/subcommands.py:343 -#: VirtualMailManager/cli/subcommands.py:372 -#: VirtualMailManager/cli/subcommands.py:509 -#: VirtualMailManager/cli/subcommands.py:522 VirtualMailManager/handler.py:453 -#: VirtualMailManager/handler.py:466 VirtualMailManager/handler.py:481 -#: VirtualMailManager/handler.py:510 VirtualMailManager/handler.py:674 -#, fuzzy, python-format -msgid "Invalid argument: '%s'" -msgstr "Paramètre invalide: “%s”" - -#: VirtualMailManager/cli/subcommands.py:267 -#: VirtualMailManager/cli/subcommands.py:273 -msgid "Domain" -msgstr "Domaine" - -#: VirtualMailManager/cli/subcommands.py:275 -#: VirtualMailManager/cli/subcommands.py:284 -msgid "accounts" -msgstr "comptes" - -#: VirtualMailManager/cli/subcommands.py:277 -#: VirtualMailManager/cli/subcommands.py:283 -#: VirtualMailManager/cli/subcommands.py:831 -msgid "alias domains" -msgstr "Alias des domaines" - -#: VirtualMailManager/cli/subcommands.py:279 -#: VirtualMailManager/cli/subcommands.py:285 -msgid "aliases" -msgstr "Alias" - -#: VirtualMailManager/cli/subcommands.py:281 -#: VirtualMailManager/cli/subcommands.py:286 -msgid "relocated users" -msgstr "Utilisateurs relocalisés" - -#: VirtualMailManager/cli/subcommands.py:292 -#, fuzzy -msgid "Missing domain name and storage value." -msgstr "Absence de nom de domaine et de nouveau transport." - -#: VirtualMailManager/cli/subcommands.py:295 -#: VirtualMailManager/cli/subcommands.py:582 -#, fuzzy -msgid "Missing storage value." -msgstr "Absence du nom des utilisateurs." - -#: VirtualMailManager/cli/subcommands.py:301 -#: VirtualMailManager/cli/subcommands.py:586 -#, fuzzy, python-format -msgid "Invalid storage value: '%s'" -msgstr "Paramètre invalide: “%s”" - -#: VirtualMailManager/cli/subcommands.py:311 -#, python-format -msgid "Neither a valid number of messages nor the keyword 'force': '%s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:319 -#: VirtualMailManager/cli/subcommands.py:595 -#, python-format -msgid "Not a valid number of messages: '%s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:354 -#: VirtualMailManager/cli/subcommands.py:609 -#, fuzzy, python-format -msgid "Invalid service arguments: %s" -msgstr "Paramètre invalide: “%s”" - -#: VirtualMailManager/cli/subcommands.py:363 -msgid "Missing domain name and new transport." -msgstr "Absence de nom de domaine et de nouveau transport." - -#: VirtualMailManager/cli/subcommands.py:366 -msgid "Missing new transport." -msgstr "Absence de nouveau transport." - -#: VirtualMailManager/cli/subcommands.py:380 -#, fuzzy -msgid "Missing UID." -msgstr "Absence d'identiant utilisateur" - -#: VirtualMailManager/cli/subcommands.py:381 -#: VirtualMailManager/cli/subcommands.py:545 -#: VirtualMailManager/cli/subcommands.py:551 -#, fuzzy -msgid "Account" -msgstr "comptes" - -#: VirtualMailManager/cli/subcommands.py:396 -#, python-format -msgid "Unknown help topic: '%s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:409 -msgid "List of available subcommands:" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:430 -msgid "Usable encoding suffixes:" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:430 -msgid "Usable password schemes:" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:451 -msgid "Missing relocated address and destination." -msgstr "Absence d'adresse relocalisée et de la destination." - -#: VirtualMailManager/cli/subcommands.py:460 -#: VirtualMailManager/cli/subcommands.py:467 -#, fuzzy -msgid "Missing relocated address." -msgstr "Absence d'adresse relocalisée" - -#: VirtualMailManager/cli/subcommands.py:490 -#: VirtualMailManager/cli/subcommands.py:503 -#: VirtualMailManager/cli/subcommands.py:516 -#: VirtualMailManager/cli/subcommands.py:568 -#: VirtualMailManager/cli/subcommands.py:603 -msgid "Missing e-mail address." -msgstr "Absence de l'adresse e-mail." - -#: VirtualMailManager/cli/subcommands.py:497 -#, fuzzy, python-format -msgid "Generated password: %s" -msgstr "Entrer un nouveau mot de passe:" - -#: VirtualMailManager/cli/subcommands.py:552 -msgid "alias addresses" -msgstr "Adresses alias" - -#: VirtualMailManager/cli/subcommands.py:558 -#, fuzzy -msgid "Missing e-mail address and user's name." -msgstr "Absence de l'adresse e-mail et du nom des utilisateurs." - -#: VirtualMailManager/cli/subcommands.py:561 -#, fuzzy -msgid "Missing user's name." -msgstr "Absence du nom des utilisateurs." - -#: VirtualMailManager/cli/subcommands.py:579 -#, fuzzy -msgid "Missing e-mail address and storage value." -msgstr "Absence de l'adresse e-mail et du nom des utilisateurs." - -#: VirtualMailManager/cli/subcommands.py:617 -msgid "Missing e-mail address and transport." -msgstr "Absence de l'adresse e-mail et du transport." - -#: VirtualMailManager/cli/subcommands.py:620 -msgid "Missing transport." -msgstr "Absence du transport." - -#: VirtualMailManager/cli/subcommands.py:630 -msgid "usage: " -msgstr "" - -#. TP: Please adjust translated words like the original text. -#. (It's a table header.) Extract from usage text: -#. usage: vmm subcommand arguments -#. short long -#. subcommand arguments -#. -#. da domainadd fqdn [transport] -#. dd domaindelete fqdn [force] -#: VirtualMailManager/cli/subcommands.py:640 -#, python-format -msgid "" -"usage: %s subcommand arguments\n" -" short long\n" -" subcommand arguments\n" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:659 -msgid "from" -msgstr "de" - -#. TP: The words 'from', 'version' and 'on' are used in -#. the version information, e.g.: -#. vmm, version 0.5.2 (from 09/09/09) -#. Python 2.5.4 on FreeBSD -#: VirtualMailManager/cli/subcommands.py:659 -msgid "version" -msgstr "version" - -#: VirtualMailManager/cli/subcommands.py:662 -msgid "on" -msgstr "sur" - -#: VirtualMailManager/cli/subcommands.py:664 -msgid "is free software and comes with ABSOLUTELY NO WARRANTY." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:672 -msgid "uid" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:673 -msgid "get the address of the user with the given UID" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:674 -#: VirtualMailManager/cli/subcommands.py:684 -msgid "address [password]" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:675 -msgid "create a new e-mail user with the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:677 -#: VirtualMailManager/cli/subcommands.py:704 -#: VirtualMailManager/cli/subcommands.py:744 -#: VirtualMailManager/cli/subcommands.py:746 -#, fuzzy -msgid "address" -msgstr "Adresses alias" - -#: VirtualMailManager/cli/subcommands.py:678 -msgid "delete the specified user" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:679 -msgid "address [details]" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:680 -msgid "display information about the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:681 -msgid "address name" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:682 -msgid "set or update the real name for an address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:685 -msgid "update the password for the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:687 -msgid "address storage [messages]" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:688 -msgid "update the quota limit for the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:690 -msgid "address [service ...]" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:691 -msgid "enables the specified services and disables all not specified services" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:694 -#, fuzzy -msgid "address transport" -msgstr "Absence du transport." - -#: VirtualMailManager/cli/subcommands.py:695 -msgid "update the transport of the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:697 -#, fuzzy -msgid "address destination ..." -msgstr "L'adresse et la destination sont identique. " - -#: VirtualMailManager/cli/subcommands.py:698 -msgid "create a new alias e-mail address with one or more destinations" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:701 -#, fuzzy -msgid "address [destination]" -msgstr "Absence de l'adresse alias et de la destination." - -#: VirtualMailManager/cli/subcommands.py:702 -msgid "delete the specified alias e-mail address or one of its destinations" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:705 -msgid "show the destination(s) of the specified alias" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:708 -#: VirtualMailManager/cli/subcommands.py:717 -msgid "fqdn destination" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:709 -msgid "create a new alias for an existing domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:711 -#: VirtualMailManager/cli/subcommands.py:714 -#: VirtualMailManager/cli/subcommands.py:723 -msgid "fqdn" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:712 -msgid "delete the specified alias domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:715 -#, fuzzy -msgid "show the destination of the given alias domain" -msgstr "Pas de destination pour l'alias de domaine relevé." - -#: VirtualMailManager/cli/subcommands.py:718 -#, fuzzy -msgid "assign the given alias domain to an other domain" -msgstr "Absence du nom de l'alias de domaine et du nom cible de domaine" - -#: VirtualMailManager/cli/subcommands.py:720 -#, fuzzy -msgid "fqdn [transport]" -msgstr "Absence du transport." - -#: VirtualMailManager/cli/subcommands.py:721 -msgid "create a new domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:724 -msgid "delete the given domain and all its alias domains" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:725 -msgid "fqdn [details]" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:726 -msgid "display information about the given domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:728 -msgid "fqdn storage [messages]" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:729 -msgid "update the quota limit of the specified domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:731 -msgid "fqdn [service ...]" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:732 -msgid "enables the specified services and disables all not specified services of the given domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:735 -#, fuzzy -msgid "fqdn transport" -msgstr "Absence du transport." - -#: VirtualMailManager/cli/subcommands.py:736 -#, fuzzy -msgid "update the transport of the specified domain" -msgstr "Soit l'identifiant du transport ou le transport doit être spécifié. " - -#: VirtualMailManager/cli/subcommands.py:737 -msgid "[pattern]" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:738 -msgid "list all domains / search domains by pattern" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:741 -#, fuzzy -msgid "address newaddress" -msgstr "Adresses alias" - -#: VirtualMailManager/cli/subcommands.py:742 -msgid "create a new record for a relocated user" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:745 -msgid "delete the record of the relocated user" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:747 -msgid "print information about a relocated user" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:749 -msgid "option" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:750 -msgid "show the actual value of the configuration option" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:751 -msgid "option value" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:752 -msgid "set a new value for the configuration option" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:753 -msgid "[section]" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:754 -msgid "start interactive configuration modus" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:756 -msgid "lists all usable password schemes and password encoding suffixes" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:758 -#, fuzzy -msgid "[subcommand]" -msgstr "Sous-commande inconue." - -#: VirtualMailManager/cli/subcommands.py:759 -msgid "show a help overview or help for the given subcommand" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:761 -msgid "show version and copyright information" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:809 -#, python-format -msgid "[%(percent)s%%] %(used)s/%(limit)s" -msgstr "" - -#. TP: used in e.g. 'Domain information' or 'Account information' -#: VirtualMailManager/cli/subcommands.py:815 -msgid "information" -msgstr "information" - -#. TP: used in e.g. 'Existing alias addresses' or 'Existing accounts' -#: VirtualMailManager/cli/subcommands.py:828 -msgid "Existing" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:841 -#: VirtualMailManager/cli/subcommands.py:883 -msgid "\tNone" -msgstr "\tAucun" - -#: VirtualMailManager/cli/subcommands.py:846 -msgid "Alias information" -msgstr "Information sur alias" - -#: VirtualMailManager/cli/subcommands.py:848 -#, python-format -msgid "\tMail for %s will be redirected to:" -msgstr "\tLes courriels pour %s vont être redirigé à:" - -#: VirtualMailManager/cli/subcommands.py:855 -msgid "Relocated information" -msgstr "Information sur la relocalisation" - -#: VirtualMailManager/cli/subcommands.py:857 -#, fuzzy, python-format -msgid "\tUser '%(addr)s' has moved to '%(dest)s'" -msgstr "\tUtilisateur “%(addr)s” a été déplacée à “%(dest)s”" - -#: VirtualMailManager/cli/subcommands.py:872 -msgid "Matching domains" -msgstr "Domaines concordant" - -#: VirtualMailManager/cli/subcommands.py:874 -#, fuzzy -msgid "Existing domains" -msgstr "Domaines concordant" - -#: VirtualMailManager/cli/subcommands.py:889 -msgid "Alias domain information" -msgstr "Information sur l'alias de domaine" - -#: VirtualMailManager/cli/subcommands.py:894 -#, python-format -msgid "" -"\tThe alias domain %(alias)s belongs to:\n" -"\t * %(domain)s" -msgstr "" -"\tL'alias de domaine %(alias)s appartiennent à:\n" -"\t * %(domain)s" - -#: VirtualMailManager/common.py:63 -#, fuzzy, python-format -msgid "No such file: '%s'" -msgstr "Pas de répertoire: %s" - -#: VirtualMailManager/common.py:66 -#, python-format -msgid "File is not executable: '%s'" -msgstr "" - -#: VirtualMailManager/common.py:82 -msgid "GiB" -msgstr "" - -#: VirtualMailManager/common.py:82 -msgid "TiB" -msgstr "" - -#: VirtualMailManager/common.py:83 -msgid "KiB" -msgstr "" - -#: VirtualMailManager/common.py:83 -msgid "MiB" -msgstr "" - -#. TP: e.g.: '%(size)s %(prefix)s' -> '118.30 MiB' -#: VirtualMailManager/common.py:87 -#, python-format -msgid "%(size)s %(prefix)s" -msgstr "" - -#: VirtualMailManager/config.py:89 -#, python-format -msgid "Not a boolean: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:127 -#, python-format -msgid "Bad format: '%s' - expected: section.option" -msgstr "" - -#: VirtualMailManager/config.py:380 -#, fuzzy, python-format -msgid "* Section: %s\n" -msgstr "absence de la section: %s\n" - -#: VirtualMailManager/config.py:390 VirtualMailManager/config.py:398 -#, fuzzy, python-format -msgid "Check of configuration file %s failed.\n" -msgstr "Utilisation du fichier configuration: %s\n" - -#: VirtualMailManager/config.py:392 -msgid "Missing options, which have no default value.\n" -msgstr "" - -#: VirtualMailManager/config.py:400 VirtualMailManager/config.py:402 -#, fuzzy -msgid "Invalid configuration values.\n" -msgstr "Utilisation du fichier configuration: %s\n" - -#: VirtualMailManager/config.py:441 VirtualMailManager/config.py:525 -#, python-format -msgid "Not a valid Dovecot version: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:447 VirtualMailManager/config.py:482 -#, python-format -msgid "Unsupported database module: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:452 VirtualMailManager/config.py:490 -#, python-format -msgid "Unknown pgsql SSL mode: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:459 VirtualMailManager/config.py:503 -#: VirtualMailManager/maillocation.py:70 -#, python-format -msgid "Unsupported mailbox format: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:475 VirtualMailManager/handler.py:283 -#: VirtualMailManager/handler.py:357 VirtualMailManager/handler.py:362 -#: VirtualMailManager/handler.py:390 -#, python-format -msgid "No such directory: %s" -msgstr "Pas de répertoire: %s" - -#: VirtualMailManager/config.py:514 -#, python-format -msgid "Not a valid size value: '%s'" -msgstr "" - -#: VirtualMailManager/domain.py:78 -#, fuzzy, python-format -msgid "The domain '%s' is an alias domain." -msgstr "Le domaine “%s” est un alias de domaine." - -#: VirtualMailManager/domain.py:108 -#, python-format -msgid "There are %(account_count)u accounts, %(alias_count)u aliases and %(relocated_count)u relocated users." -msgstr "" - -#: VirtualMailManager/domain.py:123 -#, fuzzy, python-format -msgid "The domain '%s' already exists." -msgstr "Le domaine “%s” existe déjà." - -#: VirtualMailManager/domain.py:437 -#, fuzzy -msgid "The domain name is too long" -msgstr "Le nom du domaine est trop long." - -#: VirtualMailManager/domain.py:439 -#, fuzzy, python-format -msgid "The domain name '%s' is invalid" -msgstr "Le nom du domaine “%s” est invalide." - -#: VirtualMailManager/emailaddress.py:73 -#, fuzzy, python-format -msgid "Missing the '@' sign in address: '%s'" -msgstr "Absence du signe '@' dans l'adresse e-mail “%s”. " - -#: VirtualMailManager/emailaddress.py:76 -#, fuzzy, python-format -msgid "Too many '@' signs in address: '%s'" -msgstr "Absence du signe '@' dans l'adresse e-mail “%s”. " - -#: VirtualMailManager/emailaddress.py:79 -#, fuzzy, python-format -msgid "Missing local-part in address: '%s'" -msgstr "Absence d'adresse relocalisée" - -#: VirtualMailManager/emailaddress.py:82 -#, fuzzy, python-format -msgid "Missing domain name in address: '%s'" -msgstr "Absence d'un nom de domaine après “%s@”" - -#: VirtualMailManager/emailaddress.py:145 -#, fuzzy, python-format -msgid "The local-part '%s' is too long." -msgstr "La partie locale “%s” est trop longue." - -#: VirtualMailManager/emailaddress.py:150 -#, fuzzy, python-format -msgid "The local-part '%(l_part)s' contains invalid characters: %(i_chars)s" -msgstr "La partie locale “%(lpart)s” contient des caractères invalide: %(ichrs)s" - -#: VirtualMailManager/ext/postconf.py:84 -#, fuzzy, python-format -msgid "The value '%s' does not look like a valid postfix configuration parameter name." -msgstr "La valeur “%s” ne semble pas être un nom valide pour les paramètres de configuration postfix. " - -#: VirtualMailManager/handler.py:56 -#, fuzzy -msgid "an account" -msgstr "comptes" - -#: VirtualMailManager/handler.py:57 -#, fuzzy -msgid "an alias" -msgstr "Alias" - -#: VirtualMailManager/handler.py:58 -#, fuzzy -msgid "a relocated user" -msgstr "Utilisateurs relocalisés" - -#: VirtualMailManager/handler.py:84 -msgid "" -"You are not root.\n" -"\tGood bye!\n" -msgstr "" -"Vous n'êtes pas super-utilisateur (root).\n" -"\tAu revoir!\n" - -#: VirtualMailManager/handler.py:104 -#, python-format -msgid "Could not find '%(cfg_file)s' in: '%(cfg_path)s'" -msgstr "" - -#: VirtualMailManager/handler.py:115 -#, fuzzy, python-format -msgid "" -"wrong permissions for '%(file)s': %(perms)s\n" -"`chmod 0600 %(file)s` would be great." -msgstr "" -"Changer les droits de permissions (%(perms)s) pour “%(file)s”\n" -"`chmod 0600 %(file)s` serait mieux." - -#: VirtualMailManager/handler.py:135 -#, fuzzy, python-format -msgid "" -"'%(path)s' is not a directory.\n" -"(%(cfg_file)s: section 'misc', option 'base_directory')" -msgstr "" -"“%s” n'est pas un répertoire.\n" -"(vmm.cfg: section \"domdir\", option \"base\")" - -#: VirtualMailManager/handler.py:144 -#, python-format -msgid "" -"\n" -"(%(cfg_file)s: section 'bin', option '%(option)s')" -msgstr "" - -#: VirtualMailManager/handler.py:158 VirtualMailManager/handler.py:165 -#, python-format -msgid "Unable to import database module '%s'." -msgstr "" - -#. TP: %(a_type)s will be one of: 'an account', 'an alias' or -#. 'a relocated user' -#: VirtualMailManager/handler.py:244 -#, fuzzy, python-format -msgid "There is already %(a_type)s with the address '%(address)s'." -msgstr "Il y a déjà un alias avec l'adresse “%s”." - -#: VirtualMailManager/handler.py:297 -#, python-format -msgid "'%s' is not a directory." -msgstr "" - -#: VirtualMailManager/handler.py:300 -#, fuzzy, python-format -msgid "The file/directory '%s' already exists." -msgstr "Le transfére de l'utilisateur “%s” existe déjà." - -#: VirtualMailManager/handler.py:329 -msgid "Skipped mailbox folders:" -msgstr "" - -#: VirtualMailManager/handler.py:349 -#, python-format -msgid "UID '%(uid)u' and/or GID '%(gid)u' are less than %(min_uid)u/%(min_gid)u." -msgstr "" - -#: VirtualMailManager/handler.py:354 VirtualMailManager/handler.py:387 -#, fuzzy, python-format -msgid "Found \"..\" in domain directory path: %s" -msgstr "\"..\" trouvé dans le chemins d'accès du répertoire racine de l'utilisateur (home)" - -#: VirtualMailManager/handler.py:367 -#, fuzzy -msgid "Detected owner/group mismatch in home directory." -msgstr "Défaut d'appariement détecté entre les droits propriétaire/groupe avec le répertoire de l'utilisateur (home)" - -#: VirtualMailManager/handler.py:383 -#, python-format -msgid "GID '%(gid)u' is less than '%(min_gid)u'." -msgstr "" - -#: VirtualMailManager/handler.py:394 -#, fuzzy, python-format -msgid "Detected group mismatch in domain directory: %s" -msgstr "Défaut d'appariement détecté dans le répertoire domaine" - -#: VirtualMailManager/handler.py:470 VirtualMailManager/handler.py:748 -#, fuzzy, python-format -msgid "Unknown service: '%s'" -msgstr "Service “%s” inconnu." - -#: VirtualMailManager/handler.py:587 -#, fuzzy, python-format -msgid "The pattern '%s' contains invalid characters." -msgstr "Le modèle “%s” contient des charactères invalides." - -#: VirtualMailManager/handler.py:614 -#, fuzzy -msgid "Ignored destination addresses:" -msgstr "Absence de l'adresse destination." - -#: VirtualMailManager/handler.py:619 VirtualMailManager/handler.py:769 -#, fuzzy, python-format -msgid "The destination account/alias '%s' does not exist." -msgstr "La destination compte/alias “%s” n'existe pas." - -#: VirtualMailManager/handler.py:641 -#, fuzzy, python-format -msgid "" -"The account has been successfully deleted from the database.\n" -" But an error occurred while deleting the following directory:\n" -" '%(directory)s'\n" -" Reason: %(reason)s" -msgstr "" -"Le compte a été supprimé de la base de donnée avec succès.\n" -" Mais une erreur c'est produite lors de la suppression du répertoire suivant:\n" -" “%(directory)s”\n" -" Raison: %(raeson)s" - -#: VirtualMailManager/handler.py:712 -#, python-format -msgid "Could not accept name: '%s'" -msgstr "" - -#: VirtualMailManager/handler.py:735 -#, python-format -msgid "Could not accept transport: '%s'" -msgstr "" - -#: VirtualMailManager/handler.py:779 VirtualMailManager/relocated.py:98 -#: VirtualMailManager/relocated.py:105 -#, fuzzy, python-format -msgid "The relocated user '%s' does not exist." -msgstr "L'emplacement de l'utilisateur “%s” n'existe pas." - -#: VirtualMailManager/mailbox.py:260 -#, python-format -msgid "Failed to create mailboxes: %r\n" -msgstr "" - -#: VirtualMailManager/maillocation.py:74 -msgid "Empty directory name" -msgstr "" - -#: VirtualMailManager/maillocation.py:76 -#, fuzzy, python-format -msgid "Directory name is too long: '%s'" -msgstr "Le nom du domaine est trop long." - -#: VirtualMailManager/password.py:388 -#, python-format -msgid "Unsupported password scheme: '%s'" -msgstr "" - -#: VirtualMailManager/password.py:391 -#, python-format -msgid "The password scheme '%(scheme)s' requires Dovecot >= v%(version)s." -msgstr "" - -#: VirtualMailManager/password.py:397 -msgid "Encoding suffixes for password schemes require Dovecot >= v1.1.alpha1." -msgstr "" - -#: VirtualMailManager/password.py:400 -#, python-format -msgid "Unsupported password encoding: '%s'" -msgstr "" - -#: VirtualMailManager/relocated.py:71 -msgid "Address and destination are identical." -msgstr "L'adresse et la destination sont identique. " - -#: VirtualMailManager/relocated.py:75 -#, fuzzy, python-format -msgid "The relocated user '%s' already exists." -msgstr "Le transfére de l'utilisateur “%s” existe déjà." - -#~ msgid "There is already a relocated user with the address “%s”." -#~ msgstr "Il y a déjà un utilisateur relocalisé avec cette adresse “%s”." - -#~ msgid "There is already an account with address “%s”." -#~ msgstr "Il y a déjà un compte avec l'adresse “%s”." - -#~ msgid "No destination address for alias denoted." -#~ msgstr "Pas de destination à l'adresse de l'alias relevé." - -#~ msgid "The alias “%(a)s” with destination “%(d)s” already exists." -#~ msgstr "L'alias “%(a)s” avec la destination “%(d)s” existe déjà." - -#~ msgid "The alias “%(a)s” with destination “%(d)s” doesn't exists." -#~ msgstr "L'alias “%(a)s” avec la destination “%(d)s” n'existe pas." - -#~ msgid "missing options in section %s:\n" -#~ msgstr "absence des options dans la section %s:\n" - -#~ msgid "There are accounts and aliases." -#~ msgstr "Il y a des comptes et des alias." - -#~ msgid "There are accounts." -#~ msgstr "Il y a des comptes." - -#~ msgid "There are aliases." -#~ msgstr "Il y a des alias." - -#~ msgid "“%s” looks not like an e-mail address." -#~ msgstr "“%s” ne ressemble pas à une adresse e-mail." - -#~ msgid "No localpart specified." -#~ msgstr "Pas de partie locale spécifié." - -#~ msgid "Either mid or maillocation must be specified." -#~ msgstr "Soit l'identifiant de l'emplacement e-mail ou l'emplacement e-mail doit être spécifié. " - -#~ msgid "mid must be an int/long." -#~ msgstr "L'identiant de l'emplcement e-mail doit être un entier long." - -#~ msgid "" -#~ "Invalid folder name “%s”, it may consist only of\n" -#~ "1 - 20 single byte characters (A-Z, a-z, 0-9 and _)." -#~ msgstr "" -#~ "Le nom du fichier “%s” est invalid, il peut comporté\n" -#~ "entre 1 à 20 caractères (A-Z, a-z, 0-9 est _)." - -#~ msgid "Unknown mid specified." -#~ msgstr "Identifiant de l'emplacement e-mail specifié est inconnu." - -#~ msgid "No destination address for relocated user denoted." -#~ msgstr "Pas d'adresse destination pour l'utilisateur relocalisé." - -#~ msgid "tid must be an int/long." -#~ msgstr "L'identifiant du transport doit être un entier long." - -#~ msgid "Unknown tid specified." -#~ msgstr "L'identifiant du transport spécifié est inconnu." - -#~ msgid "No “vmm.cfg” found in: /root:/usr/local/etc:/etc" -#~ msgstr "Pas de “vmm.cfg” trouvé dans: /root:/usr/local/etc:/etc" - -#~ msgid "" -#~ "“%(binary)s” doesn't exists.\n" -#~ "(vmm.cfg: section \"bin\", option \"%(option)s\")" -#~ msgstr "" -#~ "“%(binary)s” n'existe pas.\n" -#~ "(vmm.cfg: section \"bin\", option \"%(option)s\")" - -#~ msgid "" -#~ "“%(binary)s” is not executable.\n" -#~ "(vmm.cfg: section \"bin\", option \"%(option)s\")" -#~ msgstr "" -#~ "“%(binary)s” n'est pas executable.\n" -#~ "(vmm.cfg: section \"bin\", option \"%(option)s\")" - -#~ msgid "FATAL: \"..\" in domain directory path detected." -#~ msgstr "FATAL: \"..\" dans le chemins d'accès du réperoire domaine." - -#~ msgid "" -#~ "Configurtion error: \"%s\"\n" -#~ "(in section \"connfig\", option \"done\") see also: vmm.cfg(5)\n" -#~ msgstr "" -#~ "Erreur de configuration: \"%s\"\n" -#~ "(dans la section \"connfig\", option \"done\") voir aussi: vmm.cfg(5)\n" - -#~ msgid "" -#~ "The keyword “detailed” is deprecated and will be removed in a future release.\n" -#~ " Please use the keyword “full” to get full details." -#~ msgstr "" -#~ "Le mot-clé “detailed” est obselète et va être supprimé dans la futur version.\n" -#~ " Utiliser, plutôt, le mot “full” pour avoir tous les détails." - -#~ msgid "Account doesn't exists" -#~ msgstr "Le compte n'existe pas." - -#~ msgid "" -#~ "The service name “managesieve” is deprecated and will be removed\n" -#~ " in a future release.\n" -#~ " Please use the service name “sieve” instead." -#~ msgstr "" -#~ "Le nom de service “managesieve” est obselète et va être supprimé\n" -#~ " dans la futur version.\n" -#~ " Utiliser, plutôt, le nom de service “sieve”." - -#~ msgid "" -#~ "Usage: %s SUBCOMMAND OBJECT ARGS*\n" -#~ " short long\n" -#~ " subcommand object args (* = optional)\n" -#~ msgstr "" -#~ "Usage: %s SOUSCOMMANDE OBJET ARGS*\n" -#~ " short long\n" -#~ " souscommande objet args (* = facultatif)\n" - -#~ msgid "Available" -#~ msgstr "Disponible" - -#~ msgid "Available domains" -#~ msgstr "Domaines disponible" diff -r 659c4476c57c -r b678a1c43027 po/nl.po --- a/po/nl.po Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1877 +0,0 @@ -# Dutch translation of vmm -# Copyright (C) 2009 Free Software Foundation, Inc. -# This file is distributed under the same license as the vmm package. -# Erwin Poeze <erwin.poeze@gmail.com>, 2009, 2012 -# -msgid "" -msgstr "" -"Project-Id-Version: vmm 0.6.1-pre1\n" -"Report-Msgid-Bugs-To: user+vmm/tp@localhost.localdomain.org\n" -"POT-Creation-Date: 2012-09-04 00:39+0200\n" -"PO-Revision-Date: 2012-09-25 21:55+0200\n" -"Last-Translator: Erwin Poeze <erwin.poeze@gmail.com>\n" -"Language-Team: Dutch <vertaling@vrijschrift.org>\n" -"Language: nl\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n != 1);\n" - -#. TP: Hm, what “quotation marks” should be used? -#. If you are unsure have a look at: -#. http://en.wikipedia.org/wiki/Quotation_mark,_non-English_usage -#: VirtualMailManager/account.py:59 VirtualMailManager/alias.py:35 -#: VirtualMailManager/catchall.py:44 VirtualMailManager/domain.py:127 -#: VirtualMailManager/relocated.py:39 -#, python-format -msgid "The domain '%s' does not exist." -msgstr "Het domein `%s' bestaat niet." - -#: VirtualMailManager/account.py:122 -#, python-format -msgid "The mailbox format '%(mbfmt)s' requires Dovecot >= v%(version)s." -msgstr "De postbusindeling `%(mbfmt)s' vereist Dovecot >= v%(version)s." - -#: VirtualMailManager/account.py:129 VirtualMailManager/account.py:354 -#, python-format -msgid "Invalid transport '%(transport)s' for mailbox format '%(mbfmt)s'." -msgstr "Transport `%(transport)s' voor postbusindeling `%(mbfmt)s' is ongeldig." - -#: VirtualMailManager/account.py:169 VirtualMailManager/cli/handler.py:93 -#: VirtualMailManager/handler.py:680 VirtualMailManager/handler.py:764 -#: VirtualMailManager/handler.py:790 VirtualMailManager/handler.py:798 -#: VirtualMailManager/handler.py:806 VirtualMailManager/handler.py:814 -#: VirtualMailManager/handler.py:833 VirtualMailManager/handler.py:845 -#, python-format -msgid "The account '%s' does not exist." -msgstr "Account `%s' bestaat niet." - -#: VirtualMailManager/account.py:225 VirtualMailManager/account.py:246 -#: VirtualMailManager/cli/handler.py:77 VirtualMailManager/handler.py:648 -#, python-format -msgid "The account '%s' already exists." -msgstr "Account `%s' bestaat al." - -#: VirtualMailManager/account.py:228 VirtualMailManager/handler.py:786 -#, python-format -msgid "Could not accept password: '%s'" -msgstr "Dit wachtwoord is niet geaccepteerd: `%s'" - -#: VirtualMailManager/account.py:249 -#, python-format -msgid "No password set for account: '%s'" -msgstr "Wachtwoord ontbreekt voor account: `%s'" - -#: VirtualMailManager/account.py:288 -#, python-format -msgid "Unknown field: '%s'" -msgstr "Onbekend veld: `%s'" - -#: VirtualMailManager/account.py:310 VirtualMailManager/domain.py:323 -msgid "PostgreSQL-based dictionary quota requires Dovecot >= v1.1.2." -msgstr "Op postgresSQL-gebaseerd woordenlijstquotum vereist Dovecot >= v1.1.2." - -#. TP: A service (e.g. pop3 or imap) may be enabled/usable or -#. disabled/unusable for a user. -#: VirtualMailManager/account.py:378 -msgid "disabled" -msgstr "uitgeschakeld" - -#: VirtualMailManager/account.py:378 -msgid "enabled" -msgstr "ingeschakeld" - -#: VirtualMailManager/account.py:417 -#, python-format -msgid "Could not fetch information for account: '%s'" -msgstr "Ophalen van informatie voor account `%s' is mislukt." - -#: VirtualMailManager/account.py:461 -#, python-format -msgid "There are %(count)d aliases with the destination address '%(address)s'." -msgstr "Er bestaan %(count)d aliassen met het bestemmingsadres `%(address)s'." - -#: VirtualMailManager/account.py:490 -msgid "UID must be an int/long." -msgstr "UID moet een geheel getal zijn (int/long)." - -#: VirtualMailManager/account.py:492 -msgid "UID must be greater than 0." -msgstr "UID moet groter dan 0 zijn." - -#: VirtualMailManager/account.py:501 -#, python-format -msgid "There is no account with the UID: '%d'" -msgstr "Er bestaat geen account met UID: `%d'" - -#: VirtualMailManager/alias.py:60 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"Currently this alias expands into %(count)i/%(limit)i recipients.\n" -"%(count_new)i additional destination(s) will render this alias unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit" -msgstr "" -"De %(count_new)i nieuwe bestemming(en) kunnen niet aan alias `%(address)s' worden toegevoegd.\n" -"Deze alias staat nu voor %(count)i/%(limit)i ontvangers.\n" -"%(count_new)i bestemming(en) extra maken deze alias onbruikbaar.\n" -"Tip: verhoog virtual_alias_expansion_limit van Postfix." - -#: VirtualMailManager/alias.py:67 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"This alias already exceeds its expansion limit (%(count)i/%(limit)i).\n" -"So its unusable, all messages addressed to this alias will be bounced.\n" -"Hint: Delete some destination addresses." -msgstr "" -"Toevoegen van %(count_new)i nieuwe bestemming(en) aan alias `%(address)s' is mislukt.\n" -"Deze alias overschrijdt al de uitbreidingslimiet (%(count)i/%(limit)i).\n" -"Daarom is de alias onbruikbaar en zullen alle berichten die hieraan gericht zijn teruggekaatst worden.\n" -"Tip: verwijder enkele bestemmingsadressen." - -#: VirtualMailManager/alias.py:142 VirtualMailManager/alias.py:154 -#: VirtualMailManager/alias.py:161 VirtualMailManager/handler.py:709 -#, python-format -msgid "The alias '%s' does not exist." -msgstr "De alias `%s' bestaat niet." - -#: VirtualMailManager/alias.py:145 -#, python-format -msgid "The address '%(addr)s' is not a destination of the alias '%(alias)s'." -msgstr "Het adres `%(addr)s' is geen bestemming van alias `%(alias)s'." - -#: VirtualMailManager/aliasdomain.py:50 -#, python-format -msgid "The domain '%s' is a primary domain." -msgstr "Het domein `%s' is een hoofddomein." - -#: VirtualMailManager/aliasdomain.py:69 -#, python-format -msgid "The alias domain '%s' already exists." -msgstr "De domeinalias `%s' bestaat al." - -#: VirtualMailManager/aliasdomain.py:72 VirtualMailManager/aliasdomain.py:106 -msgid "No destination domain set for the alias domain." -msgstr "Domeinalias bevat geen bestemmingsdomein." - -#: VirtualMailManager/aliasdomain.py:75 VirtualMailManager/aliasdomain.py:109 -#, python-format -msgid "The target domain '%s' does not exist." -msgstr "Het bestemmingsdomein `%s' bestaat nog niet." - -#: VirtualMailManager/aliasdomain.py:88 VirtualMailManager/aliasdomain.py:112 -#: VirtualMailManager/aliasdomain.py:133 -#, python-format -msgid "The alias domain '%s' does not exist." -msgstr "De domeinalias `%s' bestaat nog niet." - -#: VirtualMailManager/aliasdomain.py:98 -#, python-format -msgid "There is no primary domain for the alias domain '%s'." -msgstr "Er bestaat geen hoofddomein voor de domeinalias `%s'." - -#: VirtualMailManager/aliasdomain.py:115 -#, python-format -msgid "The alias domain '%(alias)s' is already assigned to the domain '%(domain)s'." -msgstr "De domeinalias `%(alias)s' is al toegekend aan het domein `%(domain)s'." - -#: VirtualMailManager/catchall.py:69 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to catch-all alias for\n" -"domain '%(domain)s'. Currently this alias expands into %(count)i/%(limit)i\n" -"recipients. %(count_new)i additional destination(s) will render this alias\n" -"unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit" -msgstr "" -"De %(count_new)i nieuwe bestemming(en) kunnen niet aan alias 'catch-all'\n" -"van domeinen `%(domain)s' worden toegevoegd. Deze alias staat nu voor\n" -"%(count)i/%(limit)i ontvangers. %(count_new)i extra bestemming(en) maken\n" -"deze alias onbruikbaar.\n" -"Tip: verhoog virtual_alias_expansion_limit van Postfix." - -#: VirtualMailManager/catchall.py:77 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to catch-all alias for\n" -"domain '%(domain)s'. This alias already exceeds its expansion limit (%(count)i/%(limit)i).\n" -"So its unusable, all messages addressed to this alias will be bounced.\n" -"Hint: Delete some destination addresses." -msgstr "" -"De %(count_new)i nieuwe bestemming(en) kunnen niet aan het alias 'catch-all' van\n" -"domein `%(domain)s' worden toegevoegd. Deze alias overschrijdt al de uitbreidingslimiet\n" -"van (%(count)i/%(limit)i).\n" -"Daarom is de alias onbruikbaar en zullen alle berichten hieraan geadresseerd worden teruggekaatst.\n" -"Tip: verwijder enkele bestemmingsadressen." - -#: VirtualMailManager/catchall.py:146 VirtualMailManager/catchall.py:159 -#: VirtualMailManager/catchall.py:166 -#, python-format -msgid "There are no catch-all aliases defined for domain '%s'." -msgstr "Voor domein `%s' is geen `catch-all'-alais gedefinieerd." - -#: VirtualMailManager/catchall.py:149 -#, python-format -msgid "The address '%(addr)s' is not a destination of the catch-all alias for domain '%(domain)s'." -msgstr "Het adres `%(addr)s' is geen bestemming van alias `catch-all' van domein `%(domain)s'." - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:78 -msgid "Enter new password: " -msgstr "Voer nieuw wachtwoord in:" - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:80 -msgid "Retype new password: " -msgstr "Herhaal het wachtwoord:" - -#: VirtualMailManager/cli/__init__.py:85 VirtualMailManager/cli/config.py:53 -msgid "Too many failures - try again later." -msgstr "Teveel mislukte pogingen - probeer het later opnieuw." - -#: VirtualMailManager/cli/__init__.py:91 -msgid "Sorry, passwords do not match." -msgstr "Sorry, de wachtwoorden komen niet overeen" - -#: VirtualMailManager/cli/__init__.py:95 -msgid "Sorry, empty passwords are not permitted." -msgstr "Sorry, lege wachtwoorden zijn niet toegestaan" - -#. TP: There are some words enclosed within angle brackets '<'word'>'. They -#. are used to indicate replaceable arguments. Please do not translate them. -#. -#. The descriptions of subcommands may contain the both keywords 'domain' -#. and 'force', enclosed within single quotes. Please keep them as they are. -#. -#. TP: description of subcommand configget -#: VirtualMailManager/cli/clihelp.py:21 -msgid "" -"This subcommand is used to display the actual value\n" -"of the given configuration <option>." -msgstr "" -"Met deze nevenopdracht kan de huidige waarde van de\n" -"gegeven configuratie-<option> worden getoond." - -#. TP: description of subcommand configset -#: VirtualMailManager/cli/clihelp.py:24 -msgid "" -"Use this subcommand to set or update a single\n" -"configuration option's value. <option> is the configuration option, <value>\n" -"is the <option>'s new value." -msgstr "" -"Gebruik deze nevenopdracht om een enkelvoudige\n" -"waarde van een configuratieoptie in te stellen. <optie> is de configuratieoptie,\n" -"<value> de nieuwe waarde van <option>." - -#: VirtualMailManager/cli/clihelp.py:27 VirtualMailManager/cli/clihelp.py:42 -msgid "" -"Note: This subcommand will create a new vmm.cfg without any comments.\n" -"Your current configuration file will be backed as vmm.cfg.bak." -msgstr "" -"Opmerking: deze nevenopdracht maakt een nieuwe vmm.cfg zonder commentaar\n" -"aan. De inhoud van het huidige configuratiebestand wordt opgeslagen in vmm.cfg.bak." - -#. TP: description of subcommand configure -#: VirtualMailManager/cli/clihelp.py:30 -msgid "" -"Starts the interactive configuration for all\n" -"configuration sections." -msgstr "" -"Start het interactief configureren voor alle\n" -"configuratiesecties." - -#: VirtualMailManager/cli/clihelp.py:32 -msgid "" -"In this process the currently set value of each option will be displayed\n" -"in square brackets. If no value is configured, the default value of each\n" -"option will be displayed in square brackets. Press the return key, to accept\n" -"the displayed value." -msgstr "" -"In dit proces wordt de huidige waarde van iedere optie tussen rechte haken\n" -"getoond. Als geen waarde is opgegeven, wordt de standaardwaarde\n" -"van iedere optie tussen rechte haken getoond. Met de Enter-toets wordt\n" -"de getoonde waarde bevestigd." - -#: VirtualMailManager/cli/clihelp.py:36 -msgid "" -"If the optional argument <section> is given, only the configuration\n" -"options from the given section will be displayed and will be configurable.\n" -"The following sections are available:\n" -msgstr "" -"Als het optionele argument <section> is opgegeven, worden alleen de\n" -"configuratieopties van de opgegeven sectie getoond en zijn alleen deze\n" -"bewerkbaar. De volgende secties zijn beschikbaar:\n" - -#: VirtualMailManager/cli/clihelp.py:41 -msgid "All configuration options are described in vmm.cfg(5)." -msgstr "Alle configuratieopties staan beschreven in vmm.cfg(5)." - -#. TP: description of subcommand getuser -#: VirtualMailManager/cli/clihelp.py:45 -msgid "" -"If only the <uid> is available, for example from process\n" -"list, the subcommand getuser will show the user's address." -msgstr "" -"Als alleen de <uid> beschikbaar is, bijvoorbeeld uit de\n" -"processenlijst, dan toont de nevenopdracht \"getuser\" het\n" -"adres van de gebruiker." - -#. TP: description of subcommand listdomains -#: VirtualMailManager/cli/clihelp.py:48 -msgid "" -"This subcommand lists all available domains. All\n" -"domain names will be prefixed either with `[+]', if the domain is a primary\n" -"domain, or with `[-]', if it is an alias domain name. The output can be\n" -"limited with an optional <pattern>." -msgstr "" -"Deze nevenopdracht toont alle beschikbare domeinen. \n" -"Alle namen van primaire domeinen worden van het voorvoegsel\n" -"`[+]' voorzien; aliassen van domeinnamen krijgen een `[-]'. De\n" -"uitvoer kan worden beperkt met een optioneel <pattern>." - -#: VirtualMailManager/cli/clihelp.py:52 -#, fuzzy, python-format -msgid "" -"To perform a wild card search, the % character can be used at the start\n" -"and/or the end of the <pattern>." -msgstr "" -"Om een zoekopdracht met jokertekens uit te voeren, kan het %-teken aan het\n" -"begin en einde van het <pattern> worden gebruikt." - -#. TP: description of subcommand listpwschemes -#: VirtualMailManager/cli/clihelp.py:55 -msgid "" -"This subcommand lists all password schemes which\n" -"could be used in the vmm.cfg as value of the misc.password_scheme option.\n" -"The output varies, depending on the used Dovecot version and the system's\n" -"libc." -msgstr "" -"Deze nevenopdracht toont alle wachtwoordschema's die\n" -"in vmm.cfg gebruikt kunnen worden als waarde van de optie \n" -"misc.password_scheme. De uitvoer is afhankelijk van de gebruikte\n" -"versie van Dovecot en de libc van het systeem." - -#: VirtualMailManager/cli/clihelp.py:59 -msgid "" -"When your Dovecot installation isn't too old, you will see additionally\n" -"a few usable encoding suffixes. One of them can be appended to the password\n" -"scheme." -msgstr "" -"Als de geïnstalleerde Dovecot-versie niet te oud is, worden enkele aanvullende\n" -"codeerachtervoegsels getoond. Een daarvan kan worden toegevoegd\n" -"aan het wachtwoordschema." - -#. TP: description of subcommand version -#: VirtualMailManager/cli/clihelp.py:63 -msgid "" -"Prints vmm's version and copyright information to stdout.\n" -"After this vmm exits." -msgstr "" -"Versie van vmm en copyright-informatie naar stdout schrijven\n" -"en stoppen." - -#. TP: description of subcommand domainadd -#: VirtualMailManager/cli/clihelp.py:66 -msgid "" -"Adds the new domain into the database and creates the\n" -"domain directory." -msgstr "" -"Voegt een nieuw domein toe aan de database en maakt de\n" -"domeinmap aan." - -#: VirtualMailManager/cli/clihelp.py:68 -msgid "" -"If the optional argument <transport> is given, it will override the\n" -"default transport (domain.transport) from vmm.cfg. The specified <transport>\n" -"will be the default transport for all new accounts in this domain." -msgstr "" -"Als het optionele argument <transport> is opgegeven, wordt de standaard\n" -"transport (domain.transport) van vmmcfg overschreven. Het gespecificeerde\n" -"<transport> wordt de standaard keuze voro alle nieuwe account in dit domein." - -#: VirtualMailManager/cli/clihelp.py:71 -msgid "Configuration-related behavior:" -msgstr "Configuratiegerelateerd gedrag:" - -#: VirtualMailManager/cli/clihelp.py:73 -msgid "" -"When that option is set to true (default) vmm will automatically create\n" -"the postmaster account for the new domain and prompt for postmaster@<fqdn>'s\n" -"password." -msgstr "" -"Als die optie wordt ingesteld op 'waar' (standaard) zal vmm automatisch\n" -"het postmaster-account voor het nieuwe domein aanmaken van vragen naar het\n" -"wachtwoord voor postmaster@<fqdn>" - -#: VirtualMailManager/cli/clihelp.py:77 -msgid "" -"When the value of that option is also set to true, vmm will automatically\n" -"create the postmaster account for the new domain and print the generated\n" -"postmaster password to stdout." -msgstr "" -"Als de waarde van die optie eveneens op 'waar' wordt gezet, zal vmm\n" -"automatisch het postmaster-account voor het nieuwe domein aanmaken en het\n" -"gegenereerde wachtwoord voor postmaster naar stdout schrijven." - -#. TP: description of subcommand domaindelete -#: VirtualMailManager/cli/clihelp.py:81 -msgid "" -"This subcommand deletes the domain specified by\n" -"<fqdn>." -msgstr "" -"Deze nevenopdracht verwijderd het domein zoals\n" -"opgegeven door <fqdn>." - -#: VirtualMailManager/cli/clihelp.py:83 -msgid "" -"If there are accounts, aliases and/or relocated users assigned to the\n" -"given domain, vmm will abort the requested operation and show an error\n" -"message. If you know, what you are doing, you can specify the optional keyword\n" -"'force'." -msgstr "" -"Als er accounts, aliassen en/of verplaatste gebruikers toegekend zijn\n" -"aan het opgegeven domein, zal vmm de verzochte opdracht afbreken en een\n" -"foutmelding tonen. Als u zeker van uw zaak bent, kunt u het optionele\n" -"trefwoord\n" -" 'force' opgeven." - -#: VirtualMailManager/cli/clihelp.py:87 -msgid "" -"If you really always know what you are doing, edit your vmm.cfg and set\n" -"the option domain.force_deletion to true." -msgstr "" -"Als u zeker van uw zaak bent, bewerk dan vmm.cfg en stel de optie\n" -"domain.force_deletion in op 'true'." - -#. TP: description of subcommand domaininfo -#: VirtualMailManager/cli/clihelp.py:90 -msgid "" -"This subcommand shows some information about the\n" -"given domain." -msgstr "" -"Deze nevenopdracht toont enige informatie over het\n" -"gegeven domein." - -#: VirtualMailManager/cli/clihelp.py:92 -msgid "" -"For a more detailed information about the domain the optional argument\n" -"<details> can be specified. A possible <details> value can be one of the\n" -"following six keywords:" -msgstr "" -"Specifiekere informatie over het domein kan worden verkregen met het\n" -"optionele argument <details>. Een mogelijke waarde van <details> kan een\n" -"van de volgende zes trefwoorden zijn:" - -#. TP: description of subcommand domainquota -#: VirtualMailManager/cli/clihelp.py:97 -msgid "" -"This subcommand is used to configure a new quota\n" -"limit for the accounts of the domain - not for the domain itself." -msgstr "" -"Deze nevenopdracht wordt gebruikt om een nieuw\n" -"quotum voor de accounts van het domein op te geven - niet voor het\n" -"domein zelf." - -#: VirtualMailManager/cli/clihelp.py:99 -msgid "" -"The default quota limit for accounts is defined in the vmm.cfg\n" -"(domain.quota_bytes and domain.quota_messages)." -msgstr "" -"De standaard quotum voor accounts is opgegeven in vmm.cfg\n" -"(domain.quota_bytes en domain.quota_messages)." - -#: VirtualMailManager/cli/clihelp.py:101 -msgid "" -"The new quota limit will affect only those accounts for which the limit\n" -"has not been overridden. If you want to restore the default to all accounts,\n" -"you may pass the keyword 'force'. When the argument <messages> was omitted the\n" -"default number of messages 0 (zero) will be applied." -msgstr "" -"Een nieuw quotum is alleen van toepassing op accounts waarvan de limiet\n" -"niet is overschreven. Om alle accounts te herstellen naar de standaardwaarde\n" -"kan het trefwoord 'force' worden opgegeven. Als het argument <messages> is\n" -"weggelaten, wordt het standaard aantal berichten (0) toegepast." - -#. TP: description of subcommand domainservices -#: VirtualMailManager/cli/clihelp.py:106 -msgid "" -"To define which services could be used by the\n" -"users of the domain — with the given <fqdn> — use this subcommand." -msgstr "" -"Om op te geven welke diensten door de gebruikers\n" -"van het domein gebruikt kunnen worden - met het gegeven <fqdn> -\n" -"gebruik deze nevenopdracht." - -#: VirtualMailManager/cli/clihelp.py:108 -msgid "" -"Each specified <service> will be enabled/usable. All other services\n" -"will be deactivated/unusable. Possible <service> names are:" -msgstr "" -"Iedere opgegeven <service> wordt in-/uitgeschakeld. Alle andere\n" -"diensten worden gedeactiveerd en onbruikbaar. Mogelijke <service>-namen\n" -"zijn:" - -#: VirtualMailManager/cli/clihelp.py:111 -msgid "" -"The new service set will affect only those accounts for which the set has\n" -"not been overridden. If you want to restore the default to all accounts, you\n" -"may pass the keyword 'force'." -msgstr "" -"De nieuwe serviceverzameling heeft alleen betrekking op accounts waarvoor\n" -"de verzameling niet is overschreven. Met het trefwoord `force' kan de\n" -"standaardwaarde voor alle accounts worden hersteld." - -#. TP: description of subcommand domaintransport -#: VirtualMailManager/cli/clihelp.py:115 -msgid "" -"A new transport for the indicated domain can be\n" -"set with this subcommand." -msgstr "" -"Met deze nevenopdracht kan een nieuw transport\n" -"voor alle aangegeven domeinen worden ingesteld." - -#: VirtualMailManager/cli/clihelp.py:117 -msgid "" -"The new transport will affect only those accounts for which the transport\n" -"has not been overridden. If you want to restore the default to all accounts,\n" -"you may pass the keyword 'force'." -msgstr "" -"Het nieuwe transport heeft alleen betrekking op accounts waarvoor\n" -"het transport niet is overschreven. Met het trefwoord `force' kan de\n" -"standaardwaarde voor alle accounts worden hersteld." - -#. TP: description of subcommand domainnote -#: VirtualMailManager/cli/clihelp.py:121 -msgid "" -"With this subcommand, it is possible to attach a\n" -"note to the specified domain. Without an argument, an existing note is\n" -"removed." -msgstr "" -"Deze nevenopdracht koppelt een notitie aan het\n" -"opgegeven domein. Bij het ontbreken van een argument, wordt de bestaande\n" -"notitie verwijderd." - -#. TP: description of subcommand aliasdomainadd -#: VirtualMailManager/cli/clihelp.py:125 -msgid "" -"This subcommand adds the new alias domain\n" -"(<fqdn>) to the destination <domain> that should be aliased." -msgstr "" -"Deze nevenopdracht voegt een nieuwe domeinalias\n" -"(<fqdn>) toe aan het bestemmings<domein> dat moet worden verwezen." - -#. TP: description of subcommand aliasdomaindelete -#: VirtualMailManager/cli/clihelp.py:128 -msgid "" -"Use this subcommand if the alias domain\n" -"<fqdn> should be removed." -msgstr "" -"Gebruik deze nevenopdracht indien de domainalias\n" -"<fqdn> moet worden verwijderd." - -#. TP: description of subcommand aliasdomaininfo -#: VirtualMailManager/cli/clihelp.py:131 -msgid "" -"This subcommand shows to which domain the alias\n" -"domain <fqdn> is assigned to." -msgstr "" - -#. TP: description of subcommand aliasdomainswitch -#: VirtualMailManager/cli/clihelp.py:134 -msgid "" -"If the destination of the existing alias\n" -"domain <fqdn> should be switched to another <destination> use this\n" -"subcommand." -msgstr "" - -#. TP: description of subcommand useradd -#: VirtualMailManager/cli/clihelp.py:138 -msgid "" -"Use this subcommand to create a new e-mail account for\n" -"the given <address>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:140 -msgid "" -"If the <password> is not provided, vmm will prompt for it interactively.\n" -"When no <password> is provided and account.random_password is set to true, vmm\n" -"will generate a random password and print it to stdout after the account has\n" -"been created." -msgstr "" - -#. TP: description of subcommand userdelete -#: VirtualMailManager/cli/clihelp.py:145 -msgid "" -"Use this subcommand to delete the account with the\n" -"given <address>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:147 -msgid "" -"If there are one or more aliases with an identical destination address,\n" -"vmm will abort the requested operation and show an error message. To prevent\n" -"this, specify the optional keyword 'force'." -msgstr "" - -#. TP: description of subcommand userinfo -#: VirtualMailManager/cli/clihelp.py:151 -msgid "" -"This subcommand displays some information about the\n" -"account specified by <address>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:153 -msgid "" -"If the optional argument <details> is given some more information will be\n" -"displayed. Possible values for <details> are:" -msgstr "" - -#. TP: description of subcommand username -#: VirtualMailManager/cli/clihelp.py:157 -msgid "" -"The user's real <name> can be set/updated with this\n" -"subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:159 -msgid "If no <name> is given, the value stored for the account is erased." -msgstr "" - -#. TP: description of subcommand userpassword -#: VirtualMailManager/cli/clihelp.py:162 -msgid "" -"The password of an account can be updated with this\n" -"subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:164 -msgid "If no <password> was provided, vmm will prompt for it interactively." -msgstr "" - -#. TP: description of subcommand usernote -#: VirtualMailManager/cli/clihelp.py:167 -msgid "" -"With this subcommand, it is possible to attach a note\n" -"to the specified account. Without an argument, an existing note is\n" -"removed." -msgstr "" - -#. TP: description of subcommand userquota -#: VirtualMailManager/cli/clihelp.py:171 -msgid "" -"This subcommand is used to set a new quota limit for\n" -"the given account." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:173 -msgid "" -"When the argument <messages> was omitted the default number of messages\n" -"0 (zero) will be applied." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:175 -msgid "" -"Instead of <storage> pass the keyword 'domain' to remove the\n" -"account-specific override, causing the domain's value to be in effect." -msgstr "" - -#. TP: description of subcommand userservices -#: VirtualMailManager/cli/clihelp.py:178 -msgid "" -"To grant a user access to the specified services,\n" -"use this command." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:180 -msgid "" -"All omitted services will be deactivated/unusable for the user with the\n" -"given <address>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:182 -msgid "" -"Instead of <service> pass 'domain' to remove the account-specific\n" -"override, causing the domain's value to be in effect." -msgstr "" - -#. TP: description of subcommand usertransport -#: VirtualMailManager/cli/clihelp.py:185 -msgid "" -"A different <transport> for an account can be\n" -"specified with this subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:187 -msgid "" -"Instead of <transport> pass 'domain' to remove the account-specific\n" -"override, causing the domain's value to be in effect." -msgstr "" - -#. TP: description of subcommand aliasadd -#: VirtualMailManager/cli/clihelp.py:190 -msgid "" -"This subcommand is used to create a new alias\n" -"<address> with one or more <destination> addresses." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:192 -msgid "" -"Within the destination address, the placeholders '%n', '%d', and '%='\n" -"will be replaced by the local part, the domain, or the email address with '@'\n" -"replaced by '=' respectively. In combination with alias domains, this enables\n" -"domain-specific destinations." -msgstr "" - -#. TP: description of subcommand aliasinfo -#: VirtualMailManager/cli/clihelp.py:197 -msgid "" -"Information about the alias with the given <address>\n" -"can be displayed with this subcommand." -msgstr "" - -#. TP: description of subcommand relocatedadd -#: VirtualMailManager/cli/clihelp.py:200 -msgid "" -"A new relocated user can be created with this\n" -"subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:202 -msgid "" -"<address> is the user's ex-email address, for example\n" -"b.user@example.com, and <newaddress> points to the new email address where\n" -"the user can be reached." -msgstr "" - -#. TP: description of subcommand relocatedinfo -#: VirtualMailManager/cli/clihelp.py:206 -msgid "" -"This subcommand shows the new address of the\n" -"relocated user with the given <address>." -msgstr "" - -#. TP: description of subcommand relocateddelete -#: VirtualMailManager/cli/clihelp.py:209 -msgid "" -"Use this subcommand in order to delete the\n" -"relocated user with the given <address>." -msgstr "" - -#. TP: description of subcommand catchalladd -#: VirtualMailManager/cli/clihelp.py:212 -msgid "" -"This subcommand allows to specify destination\n" -"addresses for a domain, which shall receive mail addressed to unknown\n" -"local-parts within that domain. Those catch-all aliases hence \"catch all\" mail\n" -"to any address in the domain (unless a more specific alias, mailbox or\n" -"relocated user exists)." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:217 -msgid "" -"WARNING: Catch-all addresses can cause mail server flooding because\n" -"spammers like to deliver mail to all possible combinations of names, e.g.\n" -"to all addresses between abba@example.org and zztop@example.org." -msgstr "" - -#. TP: description of subcommand catchallinfo -#: VirtualMailManager/cli/clihelp.py:221 -msgid "" -"This subcommand displays information about catch-all\n" -"aliases defined for the domain <fqdn>." -msgstr "" - -#. TP: description of subcommand catchalldelete -#: VirtualMailManager/cli/clihelp.py:224 -msgid "" -"With this subcommand, catch-all aliases defined\n" -"for a domain can be removed, either all of them, or a single one if specified\n" -"explicitly." -msgstr "" - -#: VirtualMailManager/cli/config.py:32 -#, python-format -msgid "Enter new value for option %(option)s [%(current_value)s]: " -msgstr "Geef nieuwe waarde voor optie %(option)s [%(current_value)s]: " - -#: VirtualMailManager/cli/config.py:36 -#, python-format -msgid "Using configuration file: %s\n" -msgstr "Gebruikt configuratiebestand: %s\n" - -#: VirtualMailManager/cli/config.py:38 -#, python-format -msgid "* Configuration section: '%s'" -msgstr "* Configuratiedeel: `%s'" - -#: VirtualMailManager/cli/config.py:50 -#, python-format -msgid "Warning: %s" -msgstr "Waarschuwing: %s" - -#: VirtualMailManager/cli/handler.py:66 -#, python-format -msgid "Invalid section: '%s'" -msgstr "Ongeldig deel: `%s'" - -#: VirtualMailManager/cli/main.py:32 VirtualMailManager/cli/main.py:65 -#: VirtualMailManager/cli/main.py:68 VirtualMailManager/cli/subcommands.py:752 -#: VirtualMailManager/cli/subcommands.py:772 -#, python-format -msgid "Error: %s" -msgstr "Fout: %s" - -#: VirtualMailManager/cli/main.py:41 -msgid "You must specify a subcommand at least." -msgstr "Geef minimaal een nevenopdracht op." - -#: VirtualMailManager/cli/main.py:53 -#, python-format -msgid "Unknown subcommand: '%s'" -msgstr "Onbekende nevenopdracht: `%s'" - -#. TP: We have to cry, because root has killed/interrupted vmm -#. with Ctrl+C or Ctrl+D. -#: VirtualMailManager/cli/main.py:62 -msgid "Ouch!" -msgstr "Auw!" - -#: VirtualMailManager/cli/main.py:71 -#, python-format -msgid "Error: Unknown section: '%s'" -msgstr "Fout: onbekende sectie: `%s'" - -#: VirtualMailManager/cli/main.py:74 -#, python-format -msgid "Error: No option '%(option)s' in section: '%(section)s'" -msgstr "Fout: geen optie `%(option)s' in sectie: `%(section)s'" - -#: VirtualMailManager/cli/main.py:77 -msgid "Warnings:" -msgstr "Waarschuwingen:" - -#: VirtualMailManager/cli/subcommands.py:101 -#, python-format -msgid "Subcommand '%s' is not yet documented." -msgstr "Subopdracht `%s' is nog niet gedocumenteerd." - -#: VirtualMailManager/cli/subcommands.py:108 -#, python-format -msgid "Plan A failed ... trying Plan B: %(subcommand)s %(object)s" -msgstr "Plan A is mislukt ... Plan B proberen: %(subcommand)s %(object)s" - -#: VirtualMailManager/cli/subcommands.py:122 -msgid "Missing alias address and destination." -msgstr "Aliasadres en bestemming ontbreken." - -#: VirtualMailManager/cli/subcommands.py:125 -#: VirtualMailManager/cli/subcommands.py:212 -#: VirtualMailManager/cli/subcommands.py:557 -msgid "Missing destination address." -msgstr "Bestemmingsadres ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:132 -#: VirtualMailManager/cli/subcommands.py:142 -msgid "Missing alias address." -msgstr "Aliasadres ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:164 -#: VirtualMailManager/cli/subcommands.py:198 -msgid "Missing alias domain name and destination domain name." -msgstr "Namen aliasdomein en doeldomein ontbreken." - -#: VirtualMailManager/cli/subcommands.py:167 -#: VirtualMailManager/cli/subcommands.py:201 -msgid "Missing destination domain name." -msgstr "Naam doeldomein ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:175 -#: VirtualMailManager/cli/subcommands.py:182 -msgid "Missing alias domain name." -msgstr "Aliasdomeinnaam ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:209 -msgid "Missing domain and destination." -msgstr "Aliasadres en bestemming ontbreken." - -#: VirtualMailManager/cli/subcommands.py:219 -#: VirtualMailManager/cli/subcommands.py:229 -#: VirtualMailManager/cli/subcommands.py:271 -#: VirtualMailManager/cli/subcommands.py:287 -#: VirtualMailManager/cli/subcommands.py:300 -#: VirtualMailManager/cli/subcommands.py:394 -#: VirtualMailManager/cli/subcommands.py:443 -msgid "Missing domain name." -msgstr "Ontbrekende domeinnaam." - -#: VirtualMailManager/cli/subcommands.py:237 -msgid "Missing option name." -msgstr "Ontbrekende optienaam." - -#: VirtualMailManager/cli/subcommands.py:253 -msgid "Missing option and new value." -msgstr "Optie en nieuwe waarde ontbreken." - -#: VirtualMailManager/cli/subcommands.py:255 -msgid "Missing new configuration value." -msgstr "Waarde nieuwe configuratie ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:277 -#, python-format -msgid "Creating account for postmaster@%s" -msgstr "Account voor postmaster@%s aanmaken" - -#: VirtualMailManager/cli/subcommands.py:293 -#: VirtualMailManager/cli/subcommands.py:307 -#: VirtualMailManager/cli/subcommands.py:385 -#: VirtualMailManager/cli/subcommands.py:406 -#: VirtualMailManager/cli/subcommands.py:435 -#: VirtualMailManager/cli/subcommands.py:613 -#: VirtualMailManager/cli/subcommands.py:626 VirtualMailManager/handler.py:458 -#: VirtualMailManager/handler.py:471 VirtualMailManager/handler.py:486 -#: VirtualMailManager/handler.py:520 VirtualMailManager/handler.py:759 -#, python-format -msgid "Invalid argument: '%s'" -msgstr "Ongeldig argument: `%s'" - -#: VirtualMailManager/cli/subcommands.py:326 -#: VirtualMailManager/cli/subcommands.py:333 -msgid "Domain" -msgstr "Domein" - -#: VirtualMailManager/cli/subcommands.py:335 -#: VirtualMailManager/cli/subcommands.py:346 -msgid "accounts" -msgstr "accounts" - -#: VirtualMailManager/cli/subcommands.py:337 -#: VirtualMailManager/cli/subcommands.py:345 -#: VirtualMailManager/cli/subcommands.py:999 -msgid "alias domains" -msgstr "aliasdomeinen" - -#: VirtualMailManager/cli/subcommands.py:339 -#: VirtualMailManager/cli/subcommands.py:347 -#: VirtualMailManager/cli/subcommands.py:1068 -msgid "aliases" -msgstr "aliassen" - -#: VirtualMailManager/cli/subcommands.py:341 -#: VirtualMailManager/cli/subcommands.py:348 -#: VirtualMailManager/cli/subcommands.py:1069 -msgid "relocated users" -msgstr "verplaatste gebruikers" - -#: VirtualMailManager/cli/subcommands.py:343 -#: VirtualMailManager/cli/subcommands.py:349 -msgid "catch-all destinations" -msgstr "catch-all-bestemmingen" - -#: VirtualMailManager/cli/subcommands.py:355 -msgid "Missing domain name and storage value." -msgstr "Domeinnaam en opslagwaarde ontbreken." - -#: VirtualMailManager/cli/subcommands.py:358 -#: VirtualMailManager/cli/subcommands.py:702 -msgid "Missing storage value." -msgstr "Opslagwaarde ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:364 -#: VirtualMailManager/cli/subcommands.py:707 -#, python-format -msgid "Invalid storage value: '%s'" -msgstr "Ongeldige opslagwaarde: `%s'" - -#: VirtualMailManager/cli/subcommands.py:374 -#, python-format -msgid "Neither a valid number of messages nor the keyword 'force': '%s'" -msgstr "Noch een geldig aantal berichten, noch het trefwoord `force': `%s'" - -#: VirtualMailManager/cli/subcommands.py:382 -#: VirtualMailManager/cli/subcommands.py:718 -#, python-format -msgid "Not a valid number of messages: '%s'" -msgstr "Een ongeldig aantal berichten: `%s'" - -#: VirtualMailManager/cli/subcommands.py:417 -#: VirtualMailManager/cli/subcommands.py:732 -#, python-format -msgid "Invalid service arguments: %s" -msgstr "Ongeldige serviceargumenten: %s" - -#: VirtualMailManager/cli/subcommands.py:426 -msgid "Missing domain name and new transport." -msgstr "Domeinnaam en nieuw transport ontbreken." - -#: VirtualMailManager/cli/subcommands.py:429 -msgid "Missing new transport." -msgstr "Nieuw transport ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:455 -msgid "Missing UID." -msgstr "UID ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:456 -#: VirtualMailManager/cli/subcommands.py:649 -#: VirtualMailManager/cli/subcommands.py:657 -msgid "Account" -msgstr "Account" - -#: VirtualMailManager/cli/subcommands.py:471 -#, python-format -msgid "Unknown help topic: '%s'" -msgstr "Onbekend hulponderwerp: `%s'" - -#: VirtualMailManager/cli/subcommands.py:484 -msgid "List of available subcommands:" -msgstr "Lijst met beschikbare nevenopdrachten:" - -#: VirtualMailManager/cli/subcommands.py:507 -msgid "Usable encoding suffixes:" -msgstr "Bruikbare coderingsachtervoegsels:" - -#: VirtualMailManager/cli/subcommands.py:507 -msgid "Usable password schemes:" -msgstr "Bruikbare wachtwoordschema's:" - -#: VirtualMailManager/cli/subcommands.py:555 -msgid "Missing relocated address and destination." -msgstr "Verplaatst adres en bestemming ontbreken." - -#: VirtualMailManager/cli/subcommands.py:564 -#: VirtualMailManager/cli/subcommands.py:571 -msgid "Missing relocated address." -msgstr "Verplaatst adres ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:594 -#: VirtualMailManager/cli/subcommands.py:607 -#: VirtualMailManager/cli/subcommands.py:620 -#: VirtualMailManager/cli/subcommands.py:676 -#: VirtualMailManager/cli/subcommands.py:687 -#: VirtualMailManager/cli/subcommands.py:726 -msgid "Missing e-mail address." -msgstr "E-mailadres ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:601 -#, python-format -msgid "Generated password: %s" -msgstr "Aangemaakt wachtwoord: %s" - -#: VirtualMailManager/cli/subcommands.py:658 -msgid "alias addresses" -msgstr "Aliasadressen" - -#: VirtualMailManager/cli/subcommands.py:664 -msgid "Missing e-mail address and user's name." -msgstr "E-mailadres en gebruikersnaam ontbreken." - -#: VirtualMailManager/cli/subcommands.py:699 -msgid "Missing e-mail address and storage value." -msgstr "E-mailadres en opslagwaarde ontbreken." - -#: VirtualMailManager/cli/subcommands.py:740 -msgid "Missing e-mail address and transport." -msgstr "E-mailadres en transport ontbreken." - -#: VirtualMailManager/cli/subcommands.py:743 -msgid "Missing transport." -msgstr "Transport ontbreekt." - -#: VirtualMailManager/cli/subcommands.py:753 -msgid "usage: " -msgstr "gebruik: " - -#. TP: Please adjust translated words like the original text. -#. (It's a table header.) Extract from usage text: -#. usage: vmm subcommand arguments -#. short long -#. subcommand arguments -#. -#. da domainadd fqdn [transport] -#. dd domaindelete fqdn [force] -#: VirtualMailManager/cli/subcommands.py:763 -#, python-format -msgid "" -"usage: %s subcommand arguments\n" -" short long\n" -" subcommand arguments\n" -msgstr "" -"gebruik: %s nevenopdracht argumenten\n" -" kort lang\n" -" nevenopdracht argumenten\n" - -#: VirtualMailManager/cli/subcommands.py:782 -msgid "from" -msgstr "van" - -#. TP: The words 'from', 'version' and 'on' are used in -#. the version information, e.g.: -#. vmm, version 0.5.2 (from 09/09/09) -#. Python 2.5.4 on FreeBSD -#: VirtualMailManager/cli/subcommands.py:782 -msgid "version" -msgstr "versie" - -#: VirtualMailManager/cli/subcommands.py:785 -msgid "on" -msgstr "op" - -#: VirtualMailManager/cli/subcommands.py:787 -msgid "is free software and comes with ABSOLUTELY NO WARRANTY." -msgstr "is vrije programmatuur en komt ZONDER ENIGE GARANTIE." - -#: VirtualMailManager/cli/subcommands.py:796 -msgid "get the address of the user with the given UID" -msgstr "het adres van de gebruiker met de opgegeven UID ophalen" - -#: VirtualMailManager/cli/subcommands.py:798 -msgid "create a new e-mail user with the given address" -msgstr "een nieuwe e-mailgebruiker met het opgegeven adres aanmaken" - -#: VirtualMailManager/cli/subcommands.py:800 -msgid "delete the specified user" -msgstr "de opgegeven gebruiker verwijderen" - -#: VirtualMailManager/cli/subcommands.py:802 -msgid "display information about the given address" -msgstr "informatie over het opgegeven adres tonen" - -#: VirtualMailManager/cli/subcommands.py:804 -msgid "set, update or delete the real name for an address" -msgstr "de werkelijke naam voor een adres opgeven, bijwerken of verwijderen" - -#: VirtualMailManager/cli/subcommands.py:807 -msgid "update the password for the given address" -msgstr "het wachtwoord voor het opgegeven adres bijwerken" - -#: VirtualMailManager/cli/subcommands.py:810 -msgid "update the quota limit for the given address" -msgstr "het quotum voor het opgegeven adres bijwerken" - -#: VirtualMailManager/cli/subcommands.py:813 -msgid "enables the specified services and disables all not specified services" -msgstr "alle opgegeven diensten inschakelen en de andere diensten uitschakelen" - -#: VirtualMailManager/cli/subcommands.py:817 -msgid "update the transport of the given address" -msgstr "het transport van het opgegeven adres bijwerken" - -#: VirtualMailManager/cli/subcommands.py:819 -msgid "set, update or delete the note of the given address" -msgstr "opmerking van het opgegeven adres instellen, bijwerken of verwijderen" - -#: VirtualMailManager/cli/subcommands.py:822 -msgid "create a new alias e-mail address with one or more destinations" -msgstr "een nieuwe e-mailalias met één of meerdere bestemmingen aanmaken" - -#: VirtualMailManager/cli/subcommands.py:826 -msgid "delete the specified alias e-mail address or one of its destinations" -msgstr "het opgegeven e-mailalias of één van zijn bestemmingen verwijderen" - -#: VirtualMailManager/cli/subcommands.py:829 -msgid "show the destination(s) of the specified alias" -msgstr "de bestemming(en) van de opgegeven alias tonen" - -#: VirtualMailManager/cli/subcommands.py:833 -msgid "create a new alias for an existing domain" -msgstr "een nieuwe alias voor een bestaand domein aanmaken" - -#: VirtualMailManager/cli/subcommands.py:835 -msgid "delete the specified alias domain" -msgstr "de opgegeven domeinalias verwijderen" - -#: VirtualMailManager/cli/subcommands.py:837 -msgid "show the destination of the given alias domain" -msgstr "toon de bestemming van de opgegeven domeinalias" - -#: VirtualMailManager/cli/subcommands.py:839 -msgid "assign the given alias domain to an other domain" -msgstr "de opgegeven domeinalias toekennen aan een ander domein" - -#: VirtualMailManager/cli/subcommands.py:844 -msgid "add one or more catch-all destinations for a domain" -msgstr "één of meer 'catch-all'-bestemmingen voor een domein toevoegen" - -#: VirtualMailManager/cli/subcommands.py:848 -msgid "delete the specified catch-all destination or all of a domain's destinations" -msgstr "de opgegeven 'catch-all'-bestemming of al zijn domeinbestemmingen verwijderen" - -#: VirtualMailManager/cli/subcommands.py:851 -msgid "show the catch-all destination(s) of the specified domain" -msgstr "de 'catch-all'-bestemming(en) van het opgegeven domein tonen" - -#: VirtualMailManager/cli/subcommands.py:854 -msgid "create a new domain" -msgstr "een nieuw domein aanmaken" - -#: VirtualMailManager/cli/subcommands.py:856 -msgid "delete the given domain and all its alias domains" -msgstr "het opgegeven domein en al zijn domeinaliassen verwijderen" - -#: VirtualMailManager/cli/subcommands.py:858 -msgid "display information about the given domain" -msgstr "informatie over het opgegeven domein tonen" - -#: VirtualMailManager/cli/subcommands.py:861 -msgid "update the quota limit of the specified domain" -msgstr "het quotum van het opgegeven domein bijwerken" - -#: VirtualMailManager/cli/subcommands.py:864 -msgid "enables the specified services and disables all not specified services of the given domain" -msgstr "schakelt de opgegeven diensten in - alle niet-gespecificeerde diensten van het opgegeven domein worden uitgeschakeld" - -#: VirtualMailManager/cli/subcommands.py:868 -msgid "update the transport of the specified domain" -msgstr "transport van het opgegeven domein moet worden bijgewerkt" - -#: VirtualMailManager/cli/subcommands.py:870 -msgid "set, update or delete the note of the given domain" -msgstr "opmerking van het domein instellen, bijwerken of verwijderen" - -#: VirtualMailManager/cli/subcommands.py:873 -msgid "list all domains or search for domains by pattern" -msgstr "alle domeinen tonen of domeinen die voldoen aan zoekpatroon" - -#: VirtualMailManager/cli/subcommands.py:875 -msgid "list all addresses or search for addresses by pattern" -msgstr "alle adressen tonen of adressen die voldoen aan zoekpatroon" - -#: VirtualMailManager/cli/subcommands.py:877 -msgid "list all user accounts or search for accounts by pattern" -msgstr "alle gebruikers tonen of gebruikers die voldoen aan zoekpatroon" - -#: VirtualMailManager/cli/subcommands.py:879 -msgid "list all aliases or search for aliases by pattern" -msgstr "alle aliassen tonen of aliassen die voldoen aan zoekpatroon" - -#: VirtualMailManager/cli/subcommands.py:881 -msgid "list all relocated users or search for relocated users by pattern" -msgstr "alle verplaatste gebruikers tonen of verplaatste gebruikers die voldoen aan zoekpatroon" - -#: VirtualMailManager/cli/subcommands.py:886 -msgid "create a new record for a relocated user" -msgstr "nieuwe gegevens voor een verplaatst gebruiker aanmaken" - -#: VirtualMailManager/cli/subcommands.py:889 -msgid "delete the record of the relocated user" -msgstr "de gegevens van de verplaatste gebruiker verwijderen" - -#: VirtualMailManager/cli/subcommands.py:891 -msgid "print information about a relocated user" -msgstr "informatie over een verplaatste gebruiker tonen" - -#: VirtualMailManager/cli/subcommands.py:894 -msgid "show the actual value of the configuration option" -msgstr "de huidige waarde van de configuratieoptie tonen" - -#: VirtualMailManager/cli/subcommands.py:896 -msgid "set a new value for the configuration option" -msgstr "de configuratieoptie een nieuwe waarde geven" - -#: VirtualMailManager/cli/subcommands.py:898 -msgid "start interactive configuration mode" -msgstr "interactieve configuratiemodus starten" - -#: VirtualMailManager/cli/subcommands.py:900 -msgid "lists all usable password schemes and password encoding suffixes" -msgstr "alle bruikbare wachtwoordschema's en achtervoegsels van wachtwoordcoderingen tonen" - -#: VirtualMailManager/cli/subcommands.py:903 -msgid "show a help overview or help for the given subcommand" -msgstr "een overzicht van hulp of hulp voor de opgegeven nevenopdracht tonen" - -#: VirtualMailManager/cli/subcommands.py:905 -msgid "show version and copyright information" -msgstr "versie- en copyrightinformatie tonen" - -#. TP: e.g.: [ 0.00%] 21.09 KiB/1.00 GiB -#: VirtualMailManager/cli/subcommands.py:961 -#, python-format -msgid "[%(percent)s%%] %(used)s/%(limit)s" -msgstr "[%(percent)s%%] %(used)s/%(limit)s" - -#. TP: used in e.g. 'Domain information' or 'Account information' -#: VirtualMailManager/cli/subcommands.py:967 -msgid "information" -msgstr "informatie" - -#: VirtualMailManager/cli/subcommands.py:981 -msgid "Note" -msgstr "Opmerking" - -#. TP: used in e.g. 'Existing alias addresses' or 'Existing accounts' -#: VirtualMailManager/cli/subcommands.py:996 -msgid "Existing" -msgstr "Bestaande" - -#: VirtualMailManager/cli/subcommands.py:1009 -#: VirtualMailManager/cli/subcommands.py:1061 -#: VirtualMailManager/cli/subcommands.py:1109 -msgid "\tNone" -msgstr "\tGeen" - -#: VirtualMailManager/cli/subcommands.py:1014 -msgid "Alias information" -msgstr "Aliasinformatie" - -#: VirtualMailManager/cli/subcommands.py:1016 -#, python-format -msgid "\tMail for %s will be redirected to:" -msgstr "\tBerichten voor %s wordt doorgestuurd naar:" - -#: VirtualMailManager/cli/subcommands.py:1023 -msgid "Catch-all information" -msgstr "Catch-all-informatie" - -#: VirtualMailManager/cli/subcommands.py:1025 -#, python-format -msgid "\tMail to unknown local-parts in domain %s will be sent to:" -msgstr "Berichten naar onbekende lokaal-delen in domein %s worden gestuurd naar:" - -#: VirtualMailManager/cli/subcommands.py:1033 -msgid "Relocated information" -msgstr "Verplaatste informatie" - -#: VirtualMailManager/cli/subcommands.py:1035 -#, python-format -msgid "\tUser '%(addr)s' has moved to '%(dest)s'" -msgstr "\tGebruiker '%(addr)s' is verplaatst naar '%(dest)s'" - -#: VirtualMailManager/cli/subcommands.py:1050 -msgid "Matching domains" -msgstr "Overeenkomende domeinen" - -#: VirtualMailManager/cli/subcommands.py:1052 -msgid "Existing domains" -msgstr "Bestaande domeinen" - -#: VirtualMailManager/cli/subcommands.py:1067 -msgid "user accounts" -msgstr "Gebruikeraccounts" - -#: VirtualMailManager/cli/subcommands.py:1071 -msgid "user accounts and aliases" -msgstr "Gebruikeraccounts en aliassen" - -#: VirtualMailManager/cli/subcommands.py:1073 -msgid "user accounts and relocated users" -msgstr "gebruikeraccounts en verplaatste gebruikers" - -#: VirtualMailManager/cli/subcommands.py:1075 -msgid "aliases and relocated users" -msgstr "aliassen en verplaatste gebruikers" - -#: VirtualMailManager/cli/subcommands.py:1076 -msgid "addresses" -msgstr "Adressen" - -#: VirtualMailManager/cli/subcommands.py:1080 -#, python-format -msgid "Matching %s" -msgstr "Overeenkomende %s" - -#: VirtualMailManager/cli/subcommands.py:1082 -#, python-format -msgid "Existing %s" -msgstr "Bestaande %s" - -#: VirtualMailManager/cli/subcommands.py:1085 -#, python-format -msgid "Invalid address type for list: '%s'" -msgstr "Ongeldig adressoort voor lijst: `%s'" - -#. TP: the letters 'u', 'a' and 'r' are abbreviations of user, -#. alias and relocated user -#: VirtualMailManager/cli/subcommands.py:1097 -msgid "u" -msgstr "u" - -#: VirtualMailManager/cli/subcommands.py:1098 -msgid "a" -msgstr "a" - -#: VirtualMailManager/cli/subcommands.py:1099 -msgid "r" -msgstr "r" - -#: VirtualMailManager/cli/subcommands.py:1115 -msgid "Alias domain information" -msgstr "Aliasdomeininformatie" - -#: VirtualMailManager/cli/subcommands.py:1120 -#, python-format -msgid "" -"\tThe alias domain %(alias)s belongs to:\n" -"\t * %(domain)s" -msgstr "" -"\tDe aliasdomein %(alias)s behoort tot:\n" -"\t * %(domain)s" - -#: VirtualMailManager/common.py:63 -#, python-format -msgid "No such file: '%s'" -msgstr "Onbekend bestand: `%s'" - -#: VirtualMailManager/common.py:66 -#, python-format -msgid "File is not executable: '%s'" -msgstr "Bestand is niet uitvoerbaar: `%s'" - -#: VirtualMailManager/common.py:83 -msgid "GiB" -msgstr "GiB" - -#. TP: abbreviations of gibibyte, tebibyte kibibyte and mebibyte -#: VirtualMailManager/common.py:83 -msgid "TiB" -msgstr "TiB" - -#: VirtualMailManager/common.py:84 -msgid "KiB" -msgstr "KiB" - -#: VirtualMailManager/common.py:84 -msgid "MiB" -msgstr "MiB" - -#. TP: e.g.: '%(size)s %(prefix)s' -> '118.30 MiB' -#: VirtualMailManager/common.py:88 -#, python-format -msgid "%(size)s %(prefix)s" -msgstr "%(size)s %(prefix)s" - -#. TP: [domain default] indicates that a user's setting is the same as -#. configured in the user's domain. -#. e.g.: [ 0.84%] 42/5,000 [domain default] -#: VirtualMailManager/common.py:195 -#, python-format -msgid "%s [domain default]" -msgstr "%s [standaarddomein]" - -#: VirtualMailManager/config.py:89 -#, python-format -msgid "Not a boolean: '%s'" -msgstr "Geen boolean: `%s'" - -#: VirtualMailManager/config.py:127 -#, python-format -msgid "Bad format: '%s' - expected: section.option" -msgstr "Onjuiste vorm: `%s' - verwachtte: section.option" - -#: VirtualMailManager/config.py:378 -#, python-format -msgid "* Section: %s\n" -msgstr "* Sectie: %s\n" - -#: VirtualMailManager/config.py:388 VirtualMailManager/config.py:396 -#, python-format -msgid "Check of configuration file %s failed.\n" -msgstr "Controle van configuratiebestand %s is mislukt.\n" - -#: VirtualMailManager/config.py:390 -msgid "Missing options, which have no default value.\n" -msgstr "Onbrekende opties, zonder standaardwaarde.\n" - -#: VirtualMailManager/config.py:398 VirtualMailManager/config.py:400 -msgid "Invalid configuration values.\n" -msgstr "Configuratiewaarden zijn onjuist.\n" - -#: VirtualMailManager/config.py:439 VirtualMailManager/config.py:523 -#, python-format -msgid "Not a valid Dovecot version: '%s'" -msgstr "Ongeldige Dovecot-versie: `%s'" - -#: VirtualMailManager/config.py:445 VirtualMailManager/config.py:480 -#, python-format -msgid "Unsupported database module: '%s'" -msgstr "Niet-ondersteunde databasemodule: `%s'" - -#: VirtualMailManager/config.py:450 VirtualMailManager/config.py:488 -#, python-format -msgid "Unknown pgsql SSL mode: '%s'" -msgstr "Onbekende pgsqlr-SSL-modus: `%s'" - -#: VirtualMailManager/config.py:457 VirtualMailManager/config.py:501 -#: VirtualMailManager/maillocation.py:70 -#, python-format -msgid "Unsupported mailbox format: '%s'" -msgstr "Niet-ondersteunde postbusindeling: `%s'" - -#: VirtualMailManager/config.py:473 VirtualMailManager/handler.py:286 -#: VirtualMailManager/handler.py:362 VirtualMailManager/handler.py:367 -#: VirtualMailManager/handler.py:395 -#, python-format -msgid "No such directory: %s" -msgstr "Onbekende map: %s" - -#: VirtualMailManager/config.py:512 -#, python-format -msgid "Not a valid size value: '%s'" -msgstr "Ongeldige afmeting: `%s'" - -#: VirtualMailManager/domain.py:80 -#, python-format -msgid "The domain '%s' is an alias domain." -msgstr "Het domein `%s' is een domeinalias." - -#: VirtualMailManager/domain.py:115 -#, python-format -msgid "There are %(account_count)u accounts, %(alias_count)u aliases and %(relocated_count)u relocated users." -msgstr "Er zijn %(account_count)u accounts, %(alias_count)u aliassen en %(relocated_count)u verplaatste gebruikers." - -#: VirtualMailManager/domain.py:130 -#, python-format -msgid "The domain '%s' already exists." -msgstr "Het domein `%s' bestaat al." - -#: VirtualMailManager/domain.py:495 -msgid "The domain name is too long" -msgstr "De domeinnaam is te lang." - -#: VirtualMailManager/domain.py:497 -#, python-format -msgid "The domain name '%s' is invalid" -msgstr "De domeinnaam `%s' is ongeldig." - -#: VirtualMailManager/emailaddress.py:73 -#, python-format -msgid "Missing the '@' sign in address: '%s'" -msgstr "Ontbrekend '@'-teken in adres: `%s'" - -#: VirtualMailManager/emailaddress.py:76 -#, python-format -msgid "Too many '@' signs in address: '%s'" -msgstr "Te veel '@'-tekens in adres: `%s'" - -#: VirtualMailManager/emailaddress.py:79 -#, python-format -msgid "Missing local-part in address: '%s'" -msgstr "Lokaaldeel ontbreekt in adres: `%s'" - -#: VirtualMailManager/emailaddress.py:82 -#, python-format -msgid "Missing domain name in address: '%s'" -msgstr "De domeinnaam ontbreekt in adres: `%s'" - -#: VirtualMailManager/emailaddress.py:145 -#, python-format -msgid "The local-part '%s' is too long." -msgstr "Het lokaaldeel `%s' is te lang." - -#: VirtualMailManager/emailaddress.py:150 -#, python-format -msgid "The local-part '%(l_part)s' contains invalid characters: %(i_chars)s" -msgstr "Het lokaaldeel '%(l_part)s' bevat ongeldige tekens: %(i_chars)s" - -#: VirtualMailManager/ext/postconf.py:84 -#, python-format -msgid "The value '%s' does not look like a valid Postfix configuration parameter name." -msgstr "De waarde `%s' lijkt niet op een geldige naam voor Postfix-configuratieparameter" - -#: VirtualMailManager/handler.py:54 -msgid "an account" -msgstr "een account" - -#: VirtualMailManager/handler.py:55 -msgid "an alias" -msgstr "een alias" - -#: VirtualMailManager/handler.py:56 -msgid "a relocated user" -msgstr "een verplaatste gebruiker" - -#: VirtualMailManager/handler.py:81 -msgid "" -"You are not root.\n" -"\tGood bye!\n" -msgstr "" -"U bent geen root.\n" -"\tTot ziens!\n" - -#: VirtualMailManager/handler.py:101 -#, python-format -msgid "Could not find '%(cfg_file)s' in: '%(cfg_path)s'" -msgstr "'%(cfg_file)s' is niet gevonden in: '%(cfg_path)s'" - -#. TP: Please keep the backticks around the command. `chmod 0600 …` -#: VirtualMailManager/handler.py:113 -#, python-format -msgid "" -"wrong permissions for '%(file)s': %(perms)s\n" -"`chmod 0600 %(file)s` would be great." -msgstr "" -"pas de rechten (%(perms)s) aan voor '%(file)s'\n" -"`chmod 0600 %(file)s` is uitstekend." - -#: VirtualMailManager/handler.py:133 -#, python-format -msgid "" -"'%(path)s' is not a directory.\n" -"(%(cfg_file)s: section 'misc', option 'base_directory')" -msgstr "" -"'%(path)s' is geen map.\n" -"(%(cfg_file)s: sectie 'misc', optie 'base_directory')" - -#: VirtualMailManager/handler.py:142 -#, python-format -msgid "" -"\n" -"(%(cfg_file)s: section 'bin', option '%(option)s')" -msgstr "" -"\n" -"(%(cfg_file)s: sectie 'bin', optie '%(option)s')" - -#: VirtualMailManager/handler.py:156 VirtualMailManager/handler.py:163 -#, python-format -msgid "Unable to import database module '%s'." -msgstr "Importeren van databasemodule `%s' is mislukt." - -#. TP: %(a_type)s will be one of: 'an account', 'an alias' or -#. 'a relocated user' -#: VirtualMailManager/handler.py:242 -#, python-format -msgid "There is already %(a_type)s with the address '%(address)s'." -msgstr "Er bestaat al een %(a_type)s met het adres '%(address)s'." - -#: VirtualMailManager/handler.py:301 -#, python-format -msgid "'%s' is not a directory." -msgstr "`%s' is geen map." - -#: VirtualMailManager/handler.py:304 -#, python-format -msgid "The file/directory '%s' already exists." -msgstr "Bestand/map `%s' bestaat al." - -#: VirtualMailManager/handler.py:334 -msgid "Skipped mailbox folders:" -msgstr "Overgeslagen postbusmappen:" - -#: VirtualMailManager/handler.py:354 -#, python-format -msgid "UID '%(uid)u' and/or GID '%(gid)u' are less than %(min_uid)u/%(min_gid)u." -msgstr "UID `%(uid)u' en/of GID `%(gid)u' zijn minder dan %(min_uid)u/%(min_gid)u." - -#: VirtualMailManager/handler.py:359 VirtualMailManager/handler.py:392 -#, python-format -msgid "Found \"..\" in domain directory path: %s" -msgstr "\"..\" aangetroffen in pad van domeinmap: %s" - -#: VirtualMailManager/handler.py:372 -msgid "Detected owner/group mismatch in home directory." -msgstr "Niet-passende eigenaar/groep gevonden in persoonlijke map." - -#: VirtualMailManager/handler.py:388 -#, python-format -msgid "GID '%(gid)u' is less than '%(min_gid)u'." -msgstr "GID `%(gid)u' is minder dan `%(min_gid)u'." - -#: VirtualMailManager/handler.py:399 -#, python-format -msgid "Detected group mismatch in domain directory: %s" -msgstr "Gevonden groep hoort niet in domeinmap: %s" - -#: VirtualMailManager/handler.py:475 VirtualMailManager/handler.py:853 -#, python-format -msgid "Unknown service: '%s'" -msgstr "Service `%s' is onbekend." - -#: VirtualMailManager/handler.py:599 VirtualMailManager/handler.py:623 -#: VirtualMailManager/handler.py:636 -#, python-format -msgid "The pattern '%s' contains invalid characters." -msgstr "Het patroon `%s' bevat ongeldige tekens." - -#: VirtualMailManager/handler.py:666 VirtualMailManager/handler.py:732 -msgid "Ignored destination addresses:" -msgstr "Overgeslagen bestemmingsadressen:" - -#: VirtualMailManager/handler.py:671 VirtualMailManager/handler.py:737 -#: VirtualMailManager/handler.py:870 -#, python-format -msgid "The destination account/alias '%s' does not exist." -msgstr "Bestemmingsaccount of -alias `%s' bestaat niet." - -#: VirtualMailManager/handler.py:693 -#, python-format -msgid "" -"The account has been successfully deleted from the database.\n" -" But an error occurred while deleting the following directory:\n" -" '%(directory)s'\n" -" Reason: %(reason)s" -msgstr "" -"Het account is verwijderd uit de database.\n" -" Het verwijderen van de onderstaande map is echter mislukt:\n" -" `%(directory)s'\n" -" Oorzaak: %(reason)s" - -#: VirtualMailManager/handler.py:829 -#, python-format -msgid "Could not accept transport: '%s'" -msgstr "Transport `%s' is niet geaccepteerd." - -#: VirtualMailManager/handler.py:880 VirtualMailManager/relocated.py:106 -#: VirtualMailManager/relocated.py:113 -#, python-format -msgid "The relocated user '%s' does not exist." -msgstr "De verplaatste gebruiker `%s' bestaat niet." - -#: VirtualMailManager/mailbox.py:260 -#, python-format -msgid "Failed to create mailboxes: %r\n" -msgstr "Aanmaken van de volgende postbussen is mislukt: %r\n" - -#: VirtualMailManager/maillocation.py:74 -msgid "Empty directory name" -msgstr "Mapnaam is leeg" - -#: VirtualMailManager/maillocation.py:76 -#, python-format -msgid "Directory name is too long: '%s'" -msgstr "De domeinnaam is te lang: `%s'" - -#: VirtualMailManager/password.py:388 -#, python-format -msgid "Unsupported password scheme: '%s'" -msgstr "Wachtwoordschema `%s' wordt niet ondersteund." - -#: VirtualMailManager/password.py:391 -#, python-format -msgid "The password scheme '%(scheme)s' requires Dovecot >= v%(version)s." -msgstr "Wachtwoordschema '%(scheme)s' vereist Dovecot >= v%(version)s." - -#: VirtualMailManager/password.py:397 -msgid "Encoding suffixes for password schemes require Dovecot >= v1.1.alpha1." -msgstr "Coderingsachtervoegsels voor wachtwoordschemas vereisen Dovecot >= v1.1.alpha1." - -#: VirtualMailManager/password.py:400 -#, python-format -msgid "Unsupported password encoding: '%s'" -msgstr "Wachtwoordcodering `%s' wordt niet ondersteund" - -#: VirtualMailManager/relocated.py:62 VirtualMailManager/relocated.py:76 -msgid "The destination address' domain name must not be localhost." -msgstr "De domeinnaam van het bestemmingsadres mag niet localhost zijn." - -#: VirtualMailManager/relocated.py:79 -msgid "Address and destination are identical." -msgstr "Adres en bestemming zijn identiek." - -#: VirtualMailManager/relocated.py:83 -#, python-format -msgid "The relocated user '%s' already exists." -msgstr "De verplaatste gebruiker '%s' bestaat al." - -#~ msgid "There is already a relocated user with the address “%s”." -#~ msgstr "Er bestaat al een verplaatste gebruiker met het adres “%s”." - -#~ msgid "There is already an account with address “%s”." -#~ msgstr "Het account met adres “%s” bestaat al." - -#~ msgid "The alias “%(a)s” with destination “%(d)s” already exists." -#~ msgstr "De alias “%(a)s” met bestemming “%(d)s” bestaat al." - -#~ msgid "The alias “%(a)s” with destination “%(d)s” doesn't exists." -#~ msgstr "De alias “%(a)s” met bestemming “%(d)s” bestaat niet." - -#~ msgid "missing options in section %s:\n" -#~ msgstr "ontbrekende opties in deel %s:\n" - -#~ msgid "There are accounts." -#~ msgstr "Er zijn accounts." - -#~ msgid "There are aliases." -#~ msgstr "Er zijn aliassen." - -#~ msgid "“%s” looks not like an e-mail address." -#~ msgstr "“%s” lijkt niet op een e-mailadres." - -#~ msgid "No localpart specified." -#~ msgstr "Geen lokaaldeel opgegeven." - -#~ msgid "Either mid or maillocation must be specified." -#~ msgstr "Of MID of maillocatie moeten worden opgegeven." - -#~ msgid "mid must be an int/long." -#~ msgstr "MID moet een geheel getal zijn (int/long)." - -#~ msgid "" -#~ "Invalid folder name “%s”, it may consist only of\n" -#~ "1 - 20 single byte characters (A-Z, a-z, 0-9 and _)." -#~ msgstr "" -#~ "Mapnaam “%s” is ongeldig. Het moet bestaan uit\n" -#~ "maximaal 20 tekens (A-Z, a-z, 0-9 en _)." - -#~ msgid "Unknown mid specified." -#~ msgstr "Onbekende MID opgegeven." - -#~ msgid "No destination address for relocated user denoted." -#~ msgstr "Verplaatste gebruiker heeft geen bestemmingsadres." - -#~ msgid "tid must be an int/long." -#~ msgstr "TID moet een geheel getal zijn (int/long)." - -#~ msgid "Unknown tid specified." -#~ msgstr "Onbekende TID opgegeven." - -#~ msgid "No “vmm.cfg” found in: /root:/usr/local/etc:/etc" -#~ msgstr "“vmm.cfg” is niet gevonden in: /root:/usr/local/etc:/etc" - -#~ msgid "" -#~ "“%(binary)s” doesn't exists.\n" -#~ "(vmm.cfg: section \"bin\", option \"%(option)s\")" -#~ msgstr "" -#~ "“%(binary)s” bestaat niet.\n" -#~ "(vmm.cfg: deel \"bin\", optie \"%(option)s\")" - -#~ msgid "" -#~ "“%(binary)s” is not executable.\n" -#~ "(vmm.cfg: section \"bin\", option \"%(option)s\")" -#~ msgstr "" -#~ "“%(binary)s” is geen uitvoerbaar bestand.\n" -#~ "(vmm.cfg: deel \"bin\", optie \"%(option)s\")" - -#~ msgid "FATAL: \"..\" in domain directory path detected." -#~ msgstr "FATAAL: \"..\" in pad van domeinmap aangetroffen." - -#~ msgid "" -#~ "Configurtion error: \"%s\"\n" -#~ "(in section \"connfig\", option \"done\") see also: vmm.cfg(5)\n" -#~ msgstr "" -#~ "Configuratiefout: \"%s\"\n" -#~ "(in deel \"config\", optie \"done\") zie ook: vmm.cfg(5)\n" - -#~ msgid "" -#~ "The keyword “detailed” is deprecated and will be removed in a future release.\n" -#~ " Please use the keyword “full” to get full details." -#~ msgstr "" -#~ "Het sleutelwoord “detailed” wordt niet meer ondersteund en zal in toekomstige versies worden verwijderd.\n" -#~ " Gebruik het sleutelwoord “full” om de volledige informatie te krijgen." - -#~ msgid "Account doesn't exists" -#~ msgstr "Account bestaat niet" - -#~ msgid "" -#~ "The service name “managesieve” is deprecated and will be removed\n" -#~ " in a future release.\n" -#~ " Please use the service name “sieve” instead." -#~ msgstr "" -#~ "De servicenaam “managesieve” wordt niet langer ondersteund en zal in een\n" -#~ " toekomstige versie worden verwijderd.\n" -#~ " Gebruik in plaats hiervan de servicenaam “sieve”." - -#~ msgid "" -#~ "Usage: %s SUBCOMMAND OBJECT ARGS*\n" -#~ " short long\n" -#~ " subcommand object args (* = optional)\n" -#~ msgstr "" -#~ "Gebruik: %s SUBOPDRACHT OBJECT ARGS*\n" -#~ " kort lang\n" -#~ " subopdracht object args (* = optioneel)\n" - -#~ msgid "Available" -#~ msgstr "Beschikbaar" - -#~ msgid "Available domains" -#~ msgstr "Beschikbare domeinen" diff -r 659c4476c57c -r b678a1c43027 po/vi.po --- a/po/vi.po Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,626 +0,0 @@ -# Vietnamese translation for VMM. -# Copyright © 2009 Free Software Foundation, Inc. -# This file is distributed under the same license as the vmm package. -# Clytie Siddall <clytie@riverland.net.au>, 2009. -# -msgid "" -msgstr "" -"Project-Id-Version: vmm 0.5.2\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2009-08-25 06:07+0200\n" -"PO-Revision-Date: 2009-10-11 23:34+0930\n" -"Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n" -"Language-Team: Vietnamese <vi-VN@googlegroups.com>\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: LocFactoryEditor 1.8\n" - -#: VirtualMailManager/Account.py:36 VirtualMailManager/Relocated.py:44 -#, python-format -msgid "There is already an alias with the address “%s”." -msgstr "Đã có một bí danh với địa chỉ « %s »." - -#: VirtualMailManager/Account.py:41 VirtualMailManager/Alias.py:45 -#, python-format -msgid "There is already a relocated user with the address “%s”." -msgstr "Đã có một người dùng định vị lại với địa chỉ « %s »." - -#: VirtualMailManager/Account.py:61 VirtualMailManager/Alias.py:61 -#: VirtualMailManager/Domain.py:163 VirtualMailManager/Domain.py:189 -#: VirtualMailManager/Domain.py:220 VirtualMailManager/Relocated.py:60 -#, python-format -msgid "The domain “%s” doesn't exist yet." -msgstr "Miền « %s » không tồn tại." - -#: VirtualMailManager/Account.py:80 -#, python-format -msgid "Unknown service “%s”." -msgstr "Không nhận ra dịch vụ « %s »." - -#: VirtualMailManager/Account.py:83 VirtualMailManager/Account.py:150 -#: VirtualMailManager/Account.py:178 VirtualMailManager/Account.py:212 -#, python-format -msgid "The account “%s” doesn't exists." -msgstr "Tài khoản « %s » không tồn tại." - -#: VirtualMailManager/Account.py:145 -#, python-format -msgid "The account “%s” already exists." -msgstr "Tài khoản « %s » đã có." - -#: VirtualMailManager/Account.py:186 -msgid "enabled" -msgstr "đã bật" - -#: VirtualMailManager/Account.py:188 -msgid "disabled" -msgstr "bị tắt" - -#: VirtualMailManager/Account.py:233 -#, python-format -msgid "There are %(count)d aliases with the destination address “%(address)s”." -msgstr "Có %(count)d bí danh với địa chỉ đích đến « %(address)s »." - -#: VirtualMailManager/Account.py:241 -msgid "uid must be an int/long." -msgstr "UID phải là một số nguyên dài." - -#: VirtualMailManager/Account.py:243 -msgid "uid must be greater than 0." -msgstr "UID phải lớn hơn 0." - -#: VirtualMailManager/Account.py:251 -#, python-format -msgid "There is no account with the UID “%d”." -msgstr "Không có tài khoản với UID « %d »." - -#: VirtualMailManager/Alias.py:30 VirtualMailManager/Relocated.py:30 -msgid "Address and destination are identical." -msgstr "Địa chỉ và đích đến vẫn trùng nhau." - -#: VirtualMailManager/Alias.py:40 VirtualMailManager/Relocated.py:39 -#, python-format -msgid "There is already an account with address “%s”." -msgstr "Đã có một tài khoản với địa chỉ « %s »." - -#: VirtualMailManager/Alias.py:71 -#, python-format -msgid "" -"Can't add new destination to alias “%(address)s”.\n" -"Currently this alias expands into %(count)i recipients.\n" -"One more destination will render this alias unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit\n" -msgstr "" -"Không thể thêm vào bí danh « %(address)s » một đích đến mới.\n" -"Hiện thời bí danh này mở rộng ra %(count)i người nhận.\n" -"Một đích đến thêm nữa sẽ làm cho bí danh này vô ích.\n" -"Gợi ý: tăng giới hạn « virtual_alias_expansion_limit » của Postfix.\n" - -#: VirtualMailManager/Alias.py:80 -msgid "No destination address for alias denoted." -msgstr "Chưa ghi rõ địa chỉ đích đến cho bí danh." - -#: VirtualMailManager/Alias.py:91 -#, python-format -msgid "The alias “%(a)s” with destination “%(d)s” already exists." -msgstr "Đã có bí danh « %(a)s » với đích đến « %(d)s »." - -#: VirtualMailManager/Alias.py:106 VirtualMailManager/Alias.py:123 -#, python-format -msgid "The alias “%s” doesn't exists." -msgstr "Bí danh « %s » không tồn tại." - -#: VirtualMailManager/Alias.py:125 -#, python-format -msgid "The alias “%(a)s” with destination “%(d)s” doesn't exists." -msgstr "Bí danh « %(a)s » với đích đến « %(d)s » vẫn không tồn tại." - -#: VirtualMailManager/AliasDomain.py:32 -#, python-format -msgid "The domain “%s” is a primary domain." -msgstr "Miền « %s » là một miền chính." - -#: VirtualMailManager/AliasDomain.py:37 -#, python-format -msgid "The alias domain “%s” already exists." -msgstr "Miền bí danh « %s » đã có." - -#: VirtualMailManager/AliasDomain.py:40 VirtualMailManager/AliasDomain.py:70 -msgid "No destination domain for alias domain denoted." -msgstr "Chưa ghi rõ miền đích đến cho miền bí danh." - -#: VirtualMailManager/AliasDomain.py:43 VirtualMailManager/AliasDomain.py:73 -#, python-format -msgid "The target domain “%s” doesn't exist yet." -msgstr "Miền đích « %s » không tồn tại." - -#: VirtualMailManager/AliasDomain.py:62 -#, python-format -msgid "There is no primary domain for the alias domain “%s”." -msgstr "Không có miền chính đối với miền bí danh « %s »." - -#: VirtualMailManager/AliasDomain.py:65 VirtualMailManager/AliasDomain.py:76 -#: VirtualMailManager/AliasDomain.py:99 -#, python-format -msgid "The alias domain “%s” doesn't exist yet." -msgstr "Miền bí danh « %s » không tồn tại." - -#: VirtualMailManager/AliasDomain.py:79 -#, python-format -msgid "The alias domain “%(alias)s” is already assigned to the domain “%(domain)s”." -msgstr "Miền bí danh « %(alias)s » đã được gán cho miền « %(domain)s » vào một lúc trước." - -#: VirtualMailManager/Config.py:102 VirtualMailManager/Config.py:137 -#, python-format -msgid "Using configuration file: %s\n" -msgstr "Đang sử dụng tập tin cấu hình: %s\n" - -#: VirtualMailManager/Config.py:106 -#, python-format -msgid "missing section: %s\n" -msgstr "thiếu phần: %s\n" - -#: VirtualMailManager/Config.py:108 -#, python-format -msgid "missing options in section %s:\n" -msgstr "thiếu tuỳ chọn trong phần %s:\n" - -#: VirtualMailManager/Config.py:140 -#, python-format -msgid "* Config section: “%s”" -msgstr "* Phần cấu hình: « %s »" - -#: VirtualMailManager/Config.py:143 -#, python-format -msgid "Enter new value for option %(opt)s [%(val)s]: " -msgstr "Hãy gõ giá trị mới cho %(opt)s [%(val)s]: " - -#: VirtualMailManager/Domain.py:39 -#, python-format -msgid "The domain “%s” is an alias domain." -msgstr "Miền « %s » là một miền bí danh." - -#: VirtualMailManager/Domain.py:124 -msgid "There are accounts and aliases." -msgstr "Có cả hai tài khoản và bí danh." - -#: VirtualMailManager/Domain.py:127 -msgid "There are accounts." -msgstr "Có tài khoản." - -#: VirtualMailManager/Domain.py:130 -msgid "There are aliases." -msgstr "Có bí danh." - -#: VirtualMailManager/Domain.py:145 -#, python-format -msgid "The domain “%s” already exists." -msgstr "Miền « %s » đã có." - -#: VirtualMailManager/EmailAddress.py:46 -#, python-format -msgid "Missing '@' sign in e-mail address “%s”." -msgstr "Địa chỉ thư điện tử « %s » còn thiếu ký hiệu « @ »." - -#: VirtualMailManager/EmailAddress.py:49 -#, python-format -msgid "“%s” looks not like an e-mail address." -msgstr "« %s » không hình như một địa chỉ thư điện tử." - -#: VirtualMailManager/EmailAddress.py:54 -#, python-format -msgid "Missing domain name after “%s@”." -msgstr "Thiếu tên miền đằng sau « %s@ »." - -#: VirtualMailManager/EmailAddress.py:66 -msgid "No localpart specified." -msgstr "Chưa ghi rõ localpart." - -#: VirtualMailManager/EmailAddress.py:69 -#, python-format -msgid "The local part “%s” is too long" -msgstr "Phần cục bộ « %s » vẫn quá dài" - -#: VirtualMailManager/EmailAddress.py:76 -#, python-format -msgid "The local part “%(lpart)s” contains invalid characters: %(ichrs)s" -msgstr "Phần cục bộ « %(lpart)s » chứa ký tự sai: %(ichrs)s" - -#: VirtualMailManager/MailLocation.py:32 -msgid "Either mid or maillocation must be specified." -msgstr "Phải ghi rõ hoặc mid hoặc maillocation." - -#: VirtualMailManager/MailLocation.py:38 -msgid "mid must be an int/long." -msgstr "mid phải là một số nguyên dài." - -#: VirtualMailManager/MailLocation.py:46 -#, python-format -msgid "" -"Invalid folder name “%s”, it may consist only of\n" -"1 - 20 single byte characters (A-Z, a-z, 0-9 and _)." -msgstr "" -"Sai đặt tên thư mục « %s »:\n" -"tên này phải có chiều dài 1-20 ký tự byte đơn\n" -"(cho phép chữ cái, chữ số và dấu gạch dưới)." - -#: VirtualMailManager/MailLocation.py:59 -msgid "Unknown mid specified." -msgstr "Đã ghi rõ một mid không rõ." - -#: VirtualMailManager/Relocated.py:65 -msgid "No destination address for relocated user denoted." -msgstr "Chưa ghi rõ địa chỉ đích đến cho người dùng định vị lại." - -#: VirtualMailManager/Relocated.py:75 -#, python-format -msgid "The relocated user “%s” already exists." -msgstr "Người dùng định vị lại « %s » đã có." - -#: VirtualMailManager/Relocated.py:89 VirtualMailManager/Relocated.py:102 -#, python-format -msgid "The relocated user “%s” doesn't exists." -msgstr "Người dùng định vị lại « %s » không tồn tại." - -#: VirtualMailManager/Transport.py:29 -msgid "Either tid or transport must be specified." -msgstr "Phải ghi rõ hoặc tid hoặc truyền tải." - -#: VirtualMailManager/Transport.py:35 -msgid "tid must be an int/long." -msgstr "tid phải là một số nguyên dài." - -#: VirtualMailManager/Transport.py:63 -msgid "Unknown tid specified." -msgstr "Đã ghi rõ một tid không rõ" - -#: VirtualMailManager/VirtualMailManager.py:54 -msgid "" -"You are not root.\n" -"\tGood bye!\n" -msgstr "Tiếc là bạn không phải người chủ.\n" - -#: VirtualMailManager/VirtualMailManager.py:74 -msgid "No “vmm.cfg” found in: /root:/usr/local/etc:/etc" -msgstr "Tập tin “vmm.cfg” không tìm thấy trong: /root:/usr/local/etc:/etc" - -#: VirtualMailManager/VirtualMailManager.py:85 -#, python-format -msgid "" -"fix permissions (%(perms)s) for “%(file)s”\n" -"`chmod 0600 %(file)s` would be great." -msgstr "" -"hãy sửa chữa quyền hạn (%(perms)s)\n" -"đối với tập tin « %(file)s ». Đề nghị:\n" -"chmod 0600 %(file)s" - -#: VirtualMailManager/VirtualMailManager.py:100 -#, python-format -msgid "" -"“%s” is not a directory.\n" -"(vmm.cfg: section \"domdir\", option \"base\")" -msgstr "" -"« %s » không phải là một thư mục.\n" -"(vmm.cfg: phần \"domdir\", tuỳ chọn \"base\")" - -#: VirtualMailManager/VirtualMailManager.py:105 -#, python-format -msgid "" -"“%(binary)s” doesn't exists.\n" -"(vmm.cfg: section \"bin\", option \"%(option)s\")" -msgstr "" -"\"%(binary)s” không tồn tại.\n" -"(vmm.cfg: phần \"bin\", tuỳ chọn \"%(option)s\")" - -#: VirtualMailManager/VirtualMailManager.py:109 -#, python-format -msgid "" -"“%(binary)s” is not executable.\n" -"(vmm.cfg: section \"bin\", option \"%(option)s\")" -msgstr "" -"“%(binary)s” không thể thực hiện được.\n" -"(vmm.cfg: phần \"bin\", tuỳ chọn \"%(option)s\")" - -#: VirtualMailManager/VirtualMailManager.py:166 -msgid "The domain name is too long." -msgstr "Tên miền quá dài." - -#: VirtualMailManager/VirtualMailManager.py:169 -#, python-format -msgid "The domain name “%s” is invalid." -msgstr "Tên miền « %s » vẫn không hợp lệ." - -#: VirtualMailManager/VirtualMailManager.py:209 -msgid "Enter new password: " -msgstr "Gõ mật khẩu mới: " - -#: VirtualMailManager/VirtualMailManager.py:210 -msgid "Retype new password: " -msgstr "Gõ lại mật khẩu mới: " - -#: VirtualMailManager/VirtualMailManager.py:212 -msgid "Sorry, passwords do not match" -msgstr "Rất tiếc, hai mật khẩu không khớp." - -#: VirtualMailManager/VirtualMailManager.py:216 -msgid "Sorry, empty passwords are not permitted" -msgstr "Không cho phép gõ mật khẩu trống" - -#: VirtualMailManager/VirtualMailManager.py:265 -#: VirtualMailManager/VirtualMailManager.py:352 -#, python-format -msgid "No such directory: %s" -msgstr "Không có thư mục nào như vậy: %s" - -#: VirtualMailManager/VirtualMailManager.py:340 -msgid "Found \"..\" in home directory path." -msgstr "Tìm thấy « .. » trong đường dẫn đến thư mục chính." - -#: VirtualMailManager/VirtualMailManager.py:348 -msgid "Owner/group mismatch in home directory detected." -msgstr "Phát hiện chủ sỡ hữu không tương ứng với nhóm trong thư mục chính." - -#: VirtualMailManager/VirtualMailManager.py:364 -msgid "FATAL: \"..\" in domain directory path detected." -msgstr "NGHIÊM TRỌNG: phát hiện « .. » trong đường dẫn đến thư mục miền." - -#: VirtualMailManager/VirtualMailManager.py:370 -msgid "FATAL: group mismatch in domain directory detected" -msgstr "NGHIÊM TRỌNG: phát hiện nhóm không tương ứng trong thư mục miền" - -#: VirtualMailManager/VirtualMailManager.py:457 -#, python-format -msgid "" -"Configurtion error: \"%s\"\n" -"(in section \"connfig\", option \"done\") see also: vmm.cfg(5)\n" -msgstr "" -"Lỗi cấu hình: \"%s\"\n" -"(trong phần \"connfig\", tuỳ chọn \"done\") xem cũng: vmm.cfg(5)\n" - -#: VirtualMailManager/VirtualMailManager.py:477 -#, python-format -msgid "Invalid section: “%s”" -msgstr "Phần không hợp lệ: « %s »" - -#: VirtualMailManager/VirtualMailManager.py:487 -#: VirtualMailManager/VirtualMailManager.py:497 -#: VirtualMailManager/VirtualMailManager.py:516 -#: VirtualMailManager/VirtualMailManager.py:624 -#: VirtualMailManager/VirtualMailManager.py:655 -#, python-format -msgid "Invalid argument: “%s”" -msgstr "Đối số không hợp lệ: « %s »" - -#: VirtualMailManager/VirtualMailManager.py:520 -msgid "" -"The keyword “detailed” is deprecated and will be removed in a future release.\n" -" Please use the keyword “full” to get full details." -msgstr "" -"Từ khoá « detailed » (chi tiết) bị phản đối nên được gỡ bỏ trong một phiên bản sau.\n" -" Hãy sử dụng từ khoá « full » (đầy đủ) để lấy chi tiết." - -#: VirtualMailManager/VirtualMailManager.py:593 -#, python-format -msgid "The pattern “%s” contains invalid characters." -msgstr "Mẫu « %s » chứa ký tự không hợp lệ." - -#: VirtualMailManager/VirtualMailManager.py:619 -#, python-format -msgid "The destination account/alias “%s” doesn't exists yet." -msgstr "Tài khoản hay bí danh đích đến « %s » không tồn tại." - -#: VirtualMailManager/VirtualMailManager.py:636 -#, python-format -msgid "" -"The account has been successfully deleted from the database.\n" -" But an error occurred while deleting the following directory:\n" -" “%(directory)s”\n" -" Reason: %(raeson)s" -msgstr "" -"Tài khoản đã được xoá khỏi cơ sở dữ liệu.\n" -" Tuy nhiên, một lỗi xảy ra trong khi xoá thư mục theo đây:\n" -" « %(directory)s »\n" -" Lý do : %(raeson)s" - -#: VirtualMailManager/VirtualMailManager.py:676 -msgid "Account doesn't exists" -msgstr "Tài khoản không tồn tại" - -#: VirtualMailManager/VirtualMailManager.py:692 -#: VirtualMailManager/VirtualMailManager.py:702 -msgid "" -"The service name “managesieve” is deprecated and will be removed\n" -" in a future release.\n" -" Please use the service name “sieve” instead." -msgstr "" -"Tên dịch vụ « managesieve » bị phản đối nên được gỡ bỏ trong một phiên bản sau.\n" -" Hãy thay thế bằng tên dịch vụ « sieve »." - -#: VirtualMailManager/ext/Postconf.py:44 -#, python-format -msgid "The value “%s” looks not like a valid postfix configuration parameter name." -msgstr "Giá trị « %s » không hình như một tên tham số cấu hình Postfix hợp lệ." - -#: vmm:34 -#, python-format -msgid "" -"Usage: %s SUBCOMMAND OBJECT ARGS*\n" -" short long\n" -" subcommand object args (* = optional)\n" -msgstr "" -"Sử dụng: %s LỆNH_PHỤ ĐỐI_TƯỢNG CÁC_ĐỐI_SỐ*\n" -" ngắn dài\n" -" lệnh_phụ đối_tượng đối_số (* = vẫn tuỳ chọn)\n" - -#: vmm:73 vmm:84 vmm:494 -msgid "Error" -msgstr "Lỗi" - -#: vmm:111 -msgid "information" -msgstr "thông tin" - -#: vmm:121 -msgid "Available" -msgstr "Có mặt" - -#: vmm:124 vmm:223 vmm:229 -msgid "alias domains" -msgstr "miền bí danh" - -#: vmm:134 vmm:145 vmm:169 -msgid "\tNone" -msgstr "\tKhông có" - -#: vmm:138 -msgid "Alias information" -msgstr "Thông tin bí danh" - -#: vmm:140 -#, python-format -msgid "\tMail for %s will be redirected to:" -msgstr "\tThư tín cho %s sẽ được chuyển hướng tới:" - -#: vmm:149 -msgid "Relocated information" -msgstr "Thông tin định vị lại" - -#: vmm:151 -#, python-format -msgid "\tUser “%(addr)s” has moved to “%(dest)s”" -msgstr "\tNgười dùng « %(addr)s » đã dời sang « %(dest)s »" - -#: vmm:164 -msgid "Available domains" -msgstr "Miền sẵn sàng" - -#: vmm:166 -msgid "Matching domains" -msgstr "Miền tương ứng" - -#: vmm:180 -msgid "Alias domain information" -msgstr "Thông tin miền bí danh" - -#: vmm:186 -#, python-format -msgid "" -"\tThe alias domain %(alias)s belongs to:\n" -"\t * %(domain)s" -msgstr "" -"\tMiền bí danh %(alias)s thuộc về:\n" -"\t * %(domain)s" - -#: vmm:197 vmm:205 vmm:213 -msgid "Missing domain name." -msgstr "Thiếu tên miền." - -#: vmm:215 vmm:219 -msgid "Domain" -msgstr "Miền" - -#: vmm:221 vmm:230 -msgid "accounts" -msgstr "tài khoản" - -#: vmm:225 vmm:231 -msgid "aliases" -msgstr "bí danh" - -#: vmm:227 vmm:232 -msgid "relocated users" -msgstr "người dùng định vị lại" - -#: vmm:236 -msgid "Missing domain name and new transport." -msgstr "Thiếu tên miền và truyền tải mới." - -#: vmm:238 -msgid "Missing new transport." -msgstr "Thiếu truyền tải mới." - -#: vmm:247 vmm:262 -msgid "Missing alias domain name and target domain name." -msgstr "Thiếu tên miền bí danh và tên miền đích." - -#: vmm:249 vmm:264 -msgid "Missing target domain name." -msgstr "Thiếu tên miền đích đến." - -#: vmm:255 vmm:270 -msgid "Missing alias domain name." -msgstr "Thiếu tên miền bí danh." - -#: vmm:276 vmm:285 vmm:293 vmm:323 vmm:331 vmm:339 -msgid "Missing e-mail address." -msgstr "Thiếu địa chỉ thư điện tử." - -#: vmm:301 -msgid "alias addresses" -msgstr "địa chỉ bí danh" - -#: vmm:307 -msgid "Missing e-mail address and users name." -msgstr "Thiếu địa chỉ thư điện tử và tên của người dùng." - -#: vmm:309 -msgid "Missing users name." -msgstr "Thiếu tên của người dùng." - -#: vmm:315 -msgid "Missing e-mail address and transport." -msgstr "Thiếu địa chỉ thư điện tử và truyền tải." - -#: vmm:317 -msgid "Missing transport." -msgstr "Thiếu truyền tải." - -#: vmm:348 -msgid "Missing alias address and destination." -msgstr "Thiếu địa chỉ bí danh và đích đến." - -#: vmm:350 vmm:373 -msgid "Missing destination address." -msgstr "Thiếu địa chỉ đích đến." - -#: vmm:356 vmm:362 -msgid "Missing alias address" -msgstr "Thiếu địa chỉ bí danh" - -#: vmm:371 -msgid "Missing relocated address and destination." -msgstr "Thiếu địa chỉ định vị lại và đích đến." - -#: vmm:379 vmm:387 -msgid "Missing relocated address" -msgstr "Thiếu địa chỉ định vị lại" - -#: vmm:393 -msgid "Missing userid" -msgstr "Thiếu mã số người dùng" - -#: vmm:406 -msgid "Warnings:" -msgstr "Cảnh báo :" - -#: vmm:412 -msgid "from" -msgstr "từ" - -#: vmm:412 -msgid "version" -msgstr "phiên bản" - -#: vmm:414 -msgid "on" -msgstr "ở" - -#: vmm:488 -msgid "Unknown subcommand" -msgstr "Không nhận ra câu lệnh phụ" - -#: vmm:491 -msgid "Ouch" -msgstr "Ái" diff -r 659c4476c57c -r b678a1c43027 po/vmm.pot --- a/po/vmm.pot Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1719 +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: vmm 0.6.2\n" -"Report-Msgid-Bugs-To: user+vmm/tp@localhost.localdomain.org\n" -"POT-Creation-Date: 2014-03-23 20:10+0000\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" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#. TP: Hm, what “quotation marks” should be used? -#. If you are unsure have a look at: -#. http://en.wikipedia.org/wiki/Quotation_mark,_non-English_usage -#: VirtualMailManager/account.py:60 VirtualMailManager/alias.py:35 -#: VirtualMailManager/catchall.py:44 VirtualMailManager/domain.py:131 -#: VirtualMailManager/relocated.py:39 -#, python-format -msgid "The domain '%s' does not exist." -msgstr "" - -#: VirtualMailManager/account.py:123 -#, python-format -msgid "The mailbox format '%(mbfmt)s' requires Dovecot >= v%(version)s." -msgstr "" - -#: VirtualMailManager/account.py:166 VirtualMailManager/cli/handler.py:93 -#: VirtualMailManager/handler.py:683 VirtualMailManager/handler.py:789 -#: VirtualMailManager/handler.py:815 VirtualMailManager/handler.py:823 -#: VirtualMailManager/handler.py:831 VirtualMailManager/handler.py:839 -#: VirtualMailManager/handler.py:858 VirtualMailManager/handler.py:870 -#, python-format -msgid "The account '%s' does not exist." -msgstr "" - -#: VirtualMailManager/account.py:222 VirtualMailManager/account.py:243 -#: VirtualMailManager/cli/handler.py:77 VirtualMailManager/handler.py:651 -#, python-format -msgid "The account '%s' already exists." -msgstr "" - -#: VirtualMailManager/account.py:225 VirtualMailManager/handler.py:811 -#, python-format -msgid "Could not accept password: '%s'" -msgstr "" - -#: VirtualMailManager/account.py:246 -#, python-format -msgid "No password set for account: '%s'" -msgstr "" - -#: VirtualMailManager/account.py:285 -#, python-format -msgid "Unknown field: '%s'" -msgstr "" - -#: VirtualMailManager/account.py:307 VirtualMailManager/domain.py:331 -msgid "PostgreSQL-based dictionary quota requires Dovecot >= v1.1.2." -msgstr "" - -#. TP: A service (e.g. pop3 or imap) may be enabled/usable or -#. disabled/unusable for a user. -#: VirtualMailManager/account.py:370 -msgid "disabled" -msgstr "" - -#: VirtualMailManager/account.py:370 -msgid "enabled" -msgstr "" - -#: VirtualMailManager/account.py:409 -#, python-format -msgid "Could not fetch information for account: '%s'" -msgstr "" - -#: VirtualMailManager/account.py:453 -#, python-format -msgid "There are %(count)d aliases with the destination address '%(address)s'." -msgstr "" - -#: VirtualMailManager/account.py:482 -msgid "UID must be an int/long." -msgstr "" - -#: VirtualMailManager/account.py:484 -msgid "UID must be greater than 0." -msgstr "" - -#: VirtualMailManager/account.py:493 -#, python-format -msgid "There is no account with the UID: '%d'" -msgstr "" - -#: VirtualMailManager/alias.py:61 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"Currently this alias expands into %(count)i/%(limit)i recipients.\n" -"%(count_new)i additional destination(s) will render this alias unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit" -msgstr "" - -#: VirtualMailManager/alias.py:68 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to alias '%(address)s'.\n" -"This alias already exceeds its expansion limit (%(count)i/%(limit)i).\n" -"So its unusable, all messages addressed to this alias will be bounced.\n" -"Hint: Delete some destination addresses." -msgstr "" - -#: VirtualMailManager/alias.py:155 VirtualMailManager/alias.py:172 -#: VirtualMailManager/alias.py:179 VirtualMailManager/handler.py:712 -#, python-format -msgid "The alias '%s' does not exist." -msgstr "" - -#: VirtualMailManager/alias.py:163 -#, python-format -msgid "No suitable destinations left to remove from alias '%s'." -msgstr "" - -#: VirtualMailManager/aliasdomain.py:50 -#, python-format -msgid "The domain '%s' is a primary domain." -msgstr "" - -#: VirtualMailManager/aliasdomain.py:69 -#, python-format -msgid "The alias domain '%s' already exists." -msgstr "" - -#: VirtualMailManager/aliasdomain.py:72 VirtualMailManager/aliasdomain.py:106 -msgid "No destination domain set for the alias domain." -msgstr "" - -#: VirtualMailManager/aliasdomain.py:75 VirtualMailManager/aliasdomain.py:109 -#, python-format -msgid "The target domain '%s' does not exist." -msgstr "" - -#: VirtualMailManager/aliasdomain.py:88 VirtualMailManager/aliasdomain.py:112 -#: VirtualMailManager/aliasdomain.py:133 -#, python-format -msgid "The alias domain '%s' does not exist." -msgstr "" - -#: VirtualMailManager/aliasdomain.py:98 -#, python-format -msgid "There is no primary domain for the alias domain '%s'." -msgstr "" - -#: VirtualMailManager/aliasdomain.py:115 -#, python-format -msgid "" -"The alias domain '%(alias)s' is already assigned to the domain '%(domain)s'." -msgstr "" - -#: VirtualMailManager/catchall.py:69 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to catch-all alias for\n" -"domain '%(domain)s'. Currently this alias expands into %(count)i/%(limit)i\n" -"recipients. %(count_new)i additional destination(s) will render this alias\n" -"unusable.\n" -"Hint: Increase Postfix' virtual_alias_expansion_limit" -msgstr "" - -#: VirtualMailManager/catchall.py:77 -#, python-format -msgid "" -"Cannot add %(count_new)i new destination(s) to catch-all alias for domain\n" -"'%(domain)s'. This alias already exceeds its expansion limit (%(count)i/" -"%(limit)i).\n" -"So its unusable, all messages addressed to this alias will be bounced.\n" -"Hint: Delete some destination addresses." -msgstr "" - -#: VirtualMailManager/catchall.py:151 VirtualMailManager/catchall.py:169 -#: VirtualMailManager/catchall.py:176 -#, python-format -msgid "There are no catch-all aliases defined for domain '%s'." -msgstr "" - -#: VirtualMailManager/catchall.py:159 -#, python-format -msgid "" -"No suitable destinations left to remove from the catch-all alias of domain " -"'%s'." -msgstr "" - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:78 -msgid "Enter new password: " -msgstr "" - -#. TP: Please preserve the trailing space. -#: VirtualMailManager/cli/__init__.py:80 -msgid "Retype new password: " -msgstr "" - -#: VirtualMailManager/cli/__init__.py:85 VirtualMailManager/cli/config.py:53 -msgid "Too many failures - try again later." -msgstr "" - -#: VirtualMailManager/cli/__init__.py:91 -msgid "Sorry, passwords do not match." -msgstr "" - -#: VirtualMailManager/cli/__init__.py:95 -msgid "Sorry, empty passwords are not permitted." -msgstr "" - -#. TP: There are some words enclosed within angle brackets '<'word'>'. They -#. are used to indicate replaceable arguments. Please do not translate them. -#. -#. The descriptions of subcommands may contain the both keywords 'domain' -#. and 'force', enclosed within single quotes. Please keep them as they are. -#. -#. TP: description of subcommand configget -#: VirtualMailManager/cli/clihelp.py:21 -msgid "" -"This subcommand is used to display the actual value\n" -"of the given configuration <option>." -msgstr "" - -#. TP: description of subcommand configset -#: VirtualMailManager/cli/clihelp.py:24 -msgid "" -"Use this subcommand to set or update a single\n" -"configuration option's value. <option> is the configuration option, <value>\n" -"is the <option>'s new value." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:27 VirtualMailManager/cli/clihelp.py:42 -msgid "" -"Note: This subcommand will create a new vmm.cfg without any comments.\n" -"Your current configuration file will be backed as vmm.cfg.bak." -msgstr "" - -#. TP: description of subcommand configure -#: VirtualMailManager/cli/clihelp.py:30 -msgid "" -"Starts the interactive configuration for all\n" -"configuration sections." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:32 -msgid "" -"In this process the currently set value of each option will be displayed\n" -"in square brackets. If no value is configured, the default value of each\n" -"option will be displayed in square brackets. Press the return key, to " -"accept\n" -"the displayed value." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:36 -msgid "" -"If the optional argument <section> is given, only the configuration\n" -"options from the given section will be displayed and will be configurable.\n" -"The following sections are available:\n" -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:41 -msgid "All configuration options are described in vmm.cfg(5)." -msgstr "" - -#. TP: description of subcommand getuser -#: VirtualMailManager/cli/clihelp.py:45 -msgid "" -"If only the <uid> is available, for example from process\n" -"list, the subcommand getuser will show the user's address." -msgstr "" - -#. TP: description of subcommand listaddresses -#: VirtualMailManager/cli/clihelp.py:48 -msgid "" -"This command lists all defined addresses.\n" -"Addresses belonging to alias-domains are prefixed with a '-', addresses of\n" -"regular domains with a '+'. Additionally, the letters 'u', 'a', and 'r'\n" -"indicate the type of each address: user, alias and relocated respectively.\n" -"The output can be limited with an optional <pattern>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:53 VirtualMailManager/cli/clihelp.py:60 -#: VirtualMailManager/cli/clihelp.py:67 VirtualMailManager/cli/clihelp.py:82 -#: VirtualMailManager/cli/clihelp.py:88 -#, no-python-format -msgid "" -"To perform a wild card search, the % character can be used at the start\n" -"and/or the end of the <pattern>." -msgstr "" - -#. TP: description of subcommand listaliases -#: VirtualMailManager/cli/clihelp.py:56 -msgid "" -"This command lists all defined aliases. Aliases\n" -"belonging to alias-domains are prefixed with a '-', addresses of regular\n" -"domains with a '+'. The output can be limited with an optional <pattern>." -msgstr "" - -#. TP: description of subcommand listdomains -#: VirtualMailManager/cli/clihelp.py:63 -msgid "" -"This subcommand lists all available domains. All\n" -"domain names will be prefixed either with `[+]', if the domain is a primary\n" -"domain, or with `[-]', if it is an alias domain name. The output can be\n" -"limited with an optional <pattern>." -msgstr "" - -#. TP: description of subcommand listpwschemes -#: VirtualMailManager/cli/clihelp.py:70 -msgid "" -"This subcommand lists all password schemes which\n" -"could be used in the vmm.cfg as value of the misc.password_scheme option.\n" -"The output varies, depending on the used Dovecot version and the system's\n" -"libc." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:74 -msgid "" -"When your Dovecot installation isn't too old, you will see additionally\n" -"a few usable encoding suffixes. One of them can be appended to the password\n" -"scheme." -msgstr "" - -#. TP: description of subcommand listrelocated -#: VirtualMailManager/cli/clihelp.py:78 -msgid "" -"This command lists all defined relocated addresses.\n" -"Relocated entries belonging to alias-domains are prefixed with a '-', " -"addresses\n" -"of regular domains with a '+'. The output can be limited with an optional\n" -"<pattern>." -msgstr "" - -#. TP: description of subcommand listusers -#: VirtualMailManager/cli/clihelp.py:85 -msgid "" -"This command lists all user accounts. User accounts\n" -"belonging to alias-domains are prefixed with a '-', addresses of regular\n" -"domains with a '+'. The output can be limited with an optional <pattern>." -msgstr "" - -#. TP: description of subcommand version -#: VirtualMailManager/cli/clihelp.py:91 -msgid "" -"Prints vmm's version and copyright information to stdout.\n" -"After this vmm exits." -msgstr "" - -#. TP: description of subcommand domainadd -#: VirtualMailManager/cli/clihelp.py:94 -msgid "" -"Adds the new domain into the database and creates the\n" -"domain directory." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:96 -msgid "" -"If the optional argument <transport> is given, it will override the\n" -"default transport (domain.transport) from vmm.cfg. The specified " -"<transport>\n" -"will be the default transport for all new accounts in this domain." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:99 -msgid "Configuration-related behavior:" -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:101 -msgid "" -"When that option is set to true (default) vmm will automatically create\n" -"the postmaster account for the new domain and prompt for " -"postmaster@<fqdn>'s\n" -"password." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:105 -msgid "" -"When the value of that option is also set to true, vmm will automatically\n" -"create the postmaster account for the new domain and print the generated\n" -"postmaster password to stdout." -msgstr "" - -#. TP: description of subcommand domaindelete -#: VirtualMailManager/cli/clihelp.py:109 -msgid "" -"This subcommand deletes the domain specified by\n" -"<fqdn>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:111 -msgid "" -"If there are accounts, aliases and/or relocated users assigned to the\n" -"given domain, vmm will abort the requested operation and show an error\n" -"message. If you know, what you are doing, you can specify the optional " -"keyword\n" -"'force'." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:115 -msgid "" -"If you really always know what you are doing, edit your vmm.cfg and set\n" -"the option domain.force_deletion to true." -msgstr "" - -#. TP: description of subcommand domaininfo -#: VirtualMailManager/cli/clihelp.py:118 -msgid "" -"This subcommand shows some information about the\n" -"given domain." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:120 -msgid "" -"For a more detailed information about the domain the optional argument\n" -"<details> can be specified. A possible <details> value can be one of the\n" -"following six keywords:" -msgstr "" - -#. TP: description of subcommand domainquota -#: VirtualMailManager/cli/clihelp.py:125 -msgid "" -"This subcommand is used to configure a new quota\n" -"limit for the accounts of the domain - not for the domain itself." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:127 -msgid "" -"The default quota limit for accounts is defined in the vmm.cfg\n" -"(domain.quota_bytes and domain.quota_messages)." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:129 -msgid "" -"The new quota limit will affect only those accounts for which the limit\n" -"has not been overridden. If you want to restore the default to all " -"accounts,\n" -"you may pass the keyword 'force'. When the argument <messages> was omitted " -"the\n" -"default number of messages 0 (zero) will be applied." -msgstr "" - -#. TP: description of subcommand domainservices -#: VirtualMailManager/cli/clihelp.py:134 -msgid "" -"To define which services could be used by the\n" -"users of the domain — with the given <fqdn> — use this subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:136 -msgid "" -"Each specified <service> will be enabled/usable. All other services\n" -"will be deactivated/unusable. Possible <service> names are:" -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:139 -msgid "" -"The new service set will affect only those accounts for which the set has\n" -"not been overridden. If you want to restore the default to all accounts, " -"you\n" -"may pass the keyword 'force'." -msgstr "" - -#. TP: description of subcommand domaintransport -#: VirtualMailManager/cli/clihelp.py:143 -msgid "" -"A new transport for the indicated domain can be\n" -"set with this subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:145 -msgid "" -"The new transport will affect only those accounts for which the transport\n" -"has not been overridden. If you want to restore the default to all " -"accounts,\n" -"you may pass the keyword 'force'." -msgstr "" - -#. TP: description of subcommand domainnote -#: VirtualMailManager/cli/clihelp.py:149 -msgid "" -"With this subcommand, it is possible to attach a\n" -"note to the specified domain. Without an argument, an existing note is\n" -"removed." -msgstr "" - -#. TP: description of subcommand aliasdomainadd -#: VirtualMailManager/cli/clihelp.py:153 -msgid "" -"This subcommand adds the new alias domain\n" -"(<fqdn>) to the destination <domain> that should be aliased." -msgstr "" - -#. TP: description of subcommand aliasdomaindelete -#: VirtualMailManager/cli/clihelp.py:156 -msgid "" -"Use this subcommand if the alias domain\n" -"<fqdn> should be removed." -msgstr "" - -#. TP: description of subcommand aliasdomaininfo -#: VirtualMailManager/cli/clihelp.py:159 -msgid "" -"This subcommand shows to which domain the alias\n" -"domain <fqdn> is assigned to." -msgstr "" - -#. TP: description of subcommand aliasdomainswitch -#: VirtualMailManager/cli/clihelp.py:162 -msgid "" -"If the destination of the existing alias\n" -"domain <fqdn> should be switched to another <destination> use this\n" -"subcommand." -msgstr "" - -#. TP: description of subcommand useradd -#: VirtualMailManager/cli/clihelp.py:166 -msgid "" -"Use this subcommand to create a new e-mail account for\n" -"the given <address>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:168 -msgid "" -"If the <password> is not provided, vmm will prompt for it interactively.\n" -"When no <password> is provided and account.random_password is set to true, " -"vmm\n" -"will generate a random password and print it to stdout after the account " -"has\n" -"been created." -msgstr "" - -#. TP: description of subcommand userdelete -#: VirtualMailManager/cli/clihelp.py:173 -msgid "" -"Use this subcommand to delete the account with the\n" -"given <address>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:175 -msgid "" -"If there are one or more aliases with an identical destination address,\n" -"vmm will abort the requested operation and show an error message. To " -"prevent\n" -"this, specify the optional keyword 'force'." -msgstr "" - -#. TP: description of subcommand userinfo -#: VirtualMailManager/cli/clihelp.py:179 -msgid "" -"This subcommand displays some information about the\n" -"account specified by <address>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:181 -msgid "" -"If the optional argument <details> is given some more information will be\n" -"displayed. Possible values for <details> are:" -msgstr "" - -#. TP: description of subcommand username -#: VirtualMailManager/cli/clihelp.py:185 -msgid "" -"The user's real <name> can be set/updated with this\n" -"subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:187 -msgid "If no <name> is given, the value stored for the account is erased." -msgstr "" - -#. TP: description of subcommand userpassword -#: VirtualMailManager/cli/clihelp.py:190 -msgid "" -"The password of an account can be updated with this\n" -"subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:192 -msgid "If no <password> was provided, vmm will prompt for it interactively." -msgstr "" - -#. TP: description of subcommand usernote -#: VirtualMailManager/cli/clihelp.py:195 -msgid "" -"With this subcommand, it is possible to attach a note\n" -"to the specified account. Without an argument, an existing note is\n" -"removed." -msgstr "" - -#. TP: description of subcommand userquota -#: VirtualMailManager/cli/clihelp.py:199 -msgid "" -"This subcommand is used to set a new quota limit for\n" -"the given account." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:201 -msgid "" -"When the argument <messages> was omitted the default number of messages\n" -"0 (zero) will be applied." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:203 -msgid "" -"Instead of <storage> pass the keyword 'domain' to remove the\n" -"account-specific override, causing the domain's value to be in effect." -msgstr "" - -#. TP: description of subcommand userservices -#: VirtualMailManager/cli/clihelp.py:206 -msgid "" -"To grant a user access to the specified services,\n" -"use this command." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:208 -msgid "" -"All omitted services will be deactivated/unusable for the user with the\n" -"given <address>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:210 -msgid "" -"Instead of <service> pass 'domain' to remove the account-specific\n" -"override, causing the domain's value to be in effect." -msgstr "" - -#. TP: description of subcommand usertransport -#: VirtualMailManager/cli/clihelp.py:213 -msgid "" -"A different <transport> for an account can be\n" -"specified with this subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:215 -msgid "" -"Instead of <transport> pass 'domain' to remove the account-specific\n" -"override, causing the domain's value to be in effect." -msgstr "" - -#. TP: description of subcommand aliasadd -#: VirtualMailManager/cli/clihelp.py:218 -msgid "" -"This subcommand is used to create a new alias\n" -"<address> with one or more <destination> addresses." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:220 -msgid "" -"Within the destination address, the placeholders '%n', '%d', and '%='\n" -"will be replaced by the local part, the domain, or the email address with " -"'@'\n" -"replaced by '=' respectively. In combination with alias domains, this " -"enables\n" -"domain-specific destinations." -msgstr "" - -#. TP: description of subcommand aliasdelete -#: VirtualMailManager/cli/clihelp.py:225 -msgid "" -"This subcommand is used to delete one or multiple\n" -"<destination>s from the alias with the given <address>." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:227 -msgid "" -"When no <destination> address was specified the alias with all its\n" -"destinations will be deleted." -msgstr "" - -#. TP: description of subcommand aliasinfo -#: VirtualMailManager/cli/clihelp.py:230 -msgid "" -"Information about the alias with the given <address>\n" -"can be displayed with this subcommand." -msgstr "" - -#. TP: description of subcommand relocatedadd -#: VirtualMailManager/cli/clihelp.py:233 -msgid "" -"A new relocated user can be created with this\n" -"subcommand." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:235 -msgid "" -"<address> is the user's ex-email address, for example\n" -"b.user@example.com, and <newaddress> points to the new email address where\n" -"the user can be reached." -msgstr "" - -#. TP: description of subcommand relocatedinfo -#: VirtualMailManager/cli/clihelp.py:239 -msgid "" -"This subcommand shows the new address of the\n" -"relocated user with the given <address>." -msgstr "" - -#. TP: description of subcommand relocateddelete -#: VirtualMailManager/cli/clihelp.py:242 -msgid "" -"Use this subcommand in order to delete the\n" -"relocated user with the given <address>." -msgstr "" - -#. TP: description of subcommand catchalladd -#: VirtualMailManager/cli/clihelp.py:245 -msgid "" -"This subcommand allows to specify destination\n" -"addresses for a domain, which shall receive mail addressed to unknown\n" -"local-parts within that domain. Those catch-all aliases hence \"catch all\" " -"mail\n" -"to any address in the domain (unless a more specific alias, mailbox or\n" -"relocated user exists)." -msgstr "" - -#: VirtualMailManager/cli/clihelp.py:250 -msgid "" -"WARNING: Catch-all addresses can cause mail server flooding because\n" -"spammers like to deliver mail to all possible combinations of names, e.g.\n" -"to all addresses between abba@example.org and zztop@example.org." -msgstr "" - -#. TP: description of subcommand catchallinfo -#: VirtualMailManager/cli/clihelp.py:254 -msgid "" -"This subcommand displays information about catch-all\n" -"aliases defined for the domain <fqdn>." -msgstr "" - -#. TP: description of subcommand catchalldelete -#: VirtualMailManager/cli/clihelp.py:257 -msgid "" -"With this subcommand, catch-all aliases defined\n" -"for a domain can be removed, either all of them, or those <destination>s " -"which\n" -"were specified explicitly." -msgstr "" - -#: VirtualMailManager/cli/config.py:32 -#, python-format -msgid "Enter new value for option %(option)s [%(current_value)s]: " -msgstr "" - -#: VirtualMailManager/cli/config.py:36 -#, python-format -msgid "Using configuration file: %s\n" -msgstr "" - -#: VirtualMailManager/cli/config.py:38 -#, python-format -msgid "* Configuration section: '%s'" -msgstr "" - -#: VirtualMailManager/cli/config.py:50 -#, python-format -msgid "Warning: %s" -msgstr "" - -#: VirtualMailManager/cli/handler.py:66 -#, python-format -msgid "Invalid section: '%s'" -msgstr "" - -#: VirtualMailManager/cli/main.py:32 VirtualMailManager/cli/main.py:67 -#: VirtualMailManager/cli/main.py:70 VirtualMailManager/cli/subcommands.py:756 -#: VirtualMailManager/cli/subcommands.py:776 -#, python-format -msgid "Error: %s" -msgstr "" - -#: VirtualMailManager/cli/main.py:41 -msgid "You must specify a subcommand at least." -msgstr "" - -#: VirtualMailManager/cli/main.py:53 -#, python-format -msgid "Unknown subcommand: '%s'" -msgstr "" - -#. TP: We have to cry, because root has killed/interrupted vmm -#. with Ctrl+C or Ctrl+D. -#: VirtualMailManager/cli/main.py:62 -msgid "Ouch!" -msgstr "" - -#: VirtualMailManager/cli/main.py:66 VirtualMailManager/cli/main.py:79 -msgid "Warnings:" -msgstr "" - -#: VirtualMailManager/cli/main.py:73 -#, python-format -msgid "Error: Unknown section: '%s'" -msgstr "" - -#: VirtualMailManager/cli/main.py:76 -#, python-format -msgid "Error: No option '%(option)s' in section: '%(section)s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:101 -#, python-format -msgid "Subcommand '%s' is not yet documented." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:108 -#, python-format -msgid "Plan A failed ... trying Plan B: %(subcommand)s %(object)s" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:122 -msgid "Missing alias address and destination." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:125 -#: VirtualMailManager/cli/subcommands.py:212 -#: VirtualMailManager/cli/subcommands.py:559 -msgid "Missing destination address." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:132 -#: VirtualMailManager/cli/subcommands.py:142 -msgid "Missing alias address." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:164 -#: VirtualMailManager/cli/subcommands.py:198 -msgid "Missing alias domain name and destination domain name." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:167 -#: VirtualMailManager/cli/subcommands.py:201 -msgid "Missing destination domain name." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:175 -#: VirtualMailManager/cli/subcommands.py:182 -msgid "Missing alias domain name." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:209 -msgid "Missing domain and destination." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:219 -#: VirtualMailManager/cli/subcommands.py:229 -#: VirtualMailManager/cli/subcommands.py:271 -#: VirtualMailManager/cli/subcommands.py:287 -#: VirtualMailManager/cli/subcommands.py:300 -#: VirtualMailManager/cli/subcommands.py:394 -#: VirtualMailManager/cli/subcommands.py:443 -msgid "Missing domain name." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:237 -msgid "Missing option name." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:253 -msgid "Missing option and new value." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:255 -msgid "Missing new configuration value." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:277 -#, python-format -msgid "Creating account for postmaster@%s" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:293 -#: VirtualMailManager/cli/subcommands.py:307 -#: VirtualMailManager/cli/subcommands.py:385 -#: VirtualMailManager/cli/subcommands.py:406 -#: VirtualMailManager/cli/subcommands.py:435 -#: VirtualMailManager/cli/subcommands.py:615 -#: VirtualMailManager/cli/subcommands.py:628 VirtualMailManager/handler.py:459 -#: VirtualMailManager/handler.py:472 VirtualMailManager/handler.py:487 -#: VirtualMailManager/handler.py:521 VirtualMailManager/handler.py:784 -#, python-format -msgid "Invalid argument: '%s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:326 -#: VirtualMailManager/cli/subcommands.py:333 -msgid "Domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:335 -#: VirtualMailManager/cli/subcommands.py:346 -msgid "accounts" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:337 -#: VirtualMailManager/cli/subcommands.py:345 -#: VirtualMailManager/cli/subcommands.py:1007 -msgid "alias domains" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:339 -#: VirtualMailManager/cli/subcommands.py:347 -#: VirtualMailManager/cli/subcommands.py:1077 -msgid "aliases" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:341 -#: VirtualMailManager/cli/subcommands.py:348 -#: VirtualMailManager/cli/subcommands.py:1078 -msgid "relocated users" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:343 -#: VirtualMailManager/cli/subcommands.py:349 -msgid "catch-all destinations" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:355 -msgid "Missing domain name and storage value." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:358 -#: VirtualMailManager/cli/subcommands.py:706 -msgid "Missing storage value." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:364 -#: VirtualMailManager/cli/subcommands.py:711 -#, python-format -msgid "Invalid storage value: '%s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:374 -#, python-format -msgid "Neither a valid number of messages nor the keyword 'force': '%s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:382 -#: VirtualMailManager/cli/subcommands.py:722 -#, python-format -msgid "Not a valid number of messages: '%s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:417 -#: VirtualMailManager/cli/subcommands.py:736 -#, python-format -msgid "Invalid service arguments: %s" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:426 -msgid "Missing domain name and new transport." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:429 -msgid "Missing new transport." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:455 -msgid "Missing UID." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:456 -#: VirtualMailManager/cli/subcommands.py:653 -#: VirtualMailManager/cli/subcommands.py:661 -msgid "Account" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:471 -#, python-format -msgid "Unknown help topic: '%s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:484 -msgid "List of available subcommands:" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:507 -msgid "Usable encoding suffixes:" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:507 -msgid "Usable password schemes:" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:557 -msgid "Missing relocated address and destination." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:566 -#: VirtualMailManager/cli/subcommands.py:573 -msgid "Missing relocated address." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:596 -#: VirtualMailManager/cli/subcommands.py:609 -#: VirtualMailManager/cli/subcommands.py:622 -#: VirtualMailManager/cli/subcommands.py:680 -#: VirtualMailManager/cli/subcommands.py:691 -#: VirtualMailManager/cli/subcommands.py:730 -msgid "Missing e-mail address." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:603 -#, python-format -msgid "Generated password: %s" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:662 -msgid "alias addresses" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:668 -msgid "Missing e-mail address and user's name." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:703 -msgid "Missing e-mail address and storage value." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:744 -msgid "Missing e-mail address and transport." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:747 -msgid "Missing transport." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:757 -msgid "usage: " -msgstr "" - -#. TP: Please adjust translated words like the original text. -#. (It's a table header.) Extract from usage text: -#. usage: vmm subcommand arguments -#. short long -#. subcommand arguments -#. -#. da domainadd fqdn [transport] -#. dd domaindelete fqdn [force] -#: VirtualMailManager/cli/subcommands.py:767 -#, python-format -msgid "" -"usage: %s subcommand arguments\n" -" short long\n" -" subcommand arguments\n" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:786 -msgid "from" -msgstr "" - -#. TP: The words 'from', 'version' and 'on' are used in -#. the version information, e.g.: -#. vmm, version 0.5.2 (from 09/09/09) -#. Python 2.5.4 on FreeBSD -#: VirtualMailManager/cli/subcommands.py:786 -msgid "version" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:789 -msgid "on" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:791 -msgid "is free software and comes with ABSOLUTELY NO WARRANTY." -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:800 -msgid "get the address of the user with the given UID" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:802 -msgid "create a new e-mail user with the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:804 -msgid "delete the specified user" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:806 -msgid "display information about the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:808 -msgid "set, update or delete the real name for an address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:811 -msgid "update the password for the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:814 -msgid "update the quota limit for the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:817 -msgid "enables the specified services and disables all not specified services" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:821 -msgid "update the transport of the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:823 -msgid "set, update or delete the note of the given address" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:826 -msgid "create a new alias e-mail address with one or more destinations" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:830 -msgid "delete the specified alias e-mail address or one of its destinations" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:833 -msgid "show the destination(s) of the specified alias" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:837 -msgid "create a new alias for an existing domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:839 -msgid "delete the specified alias domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:841 -msgid "show the destination of the given alias domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:843 -msgid "assign the given alias domain to an other domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:848 -msgid "add one or more catch-all destinations for a domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:852 -msgid "" -"delete the specified catch-all destination or all of a domain's destinations" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:855 -msgid "show the catch-all destination(s) of the specified domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:859 -msgid "create a new domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:861 -msgid "delete the given domain and all its alias domains" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:863 -msgid "display information about the given domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:866 -msgid "update the quota limit of the specified domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:869 -msgid "" -"enables the specified services and disables all not specified services of " -"the given domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:873 -msgid "update the transport of the specified domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:875 -msgid "set, update or delete the note of the given domain" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:878 -msgid "list all domains or search for domains by pattern" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:880 -msgid "list all addresses or search for addresses by pattern" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:883 -msgid "list all user accounts or search for accounts by pattern" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:886 -msgid "list all aliases or search for aliases by pattern" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:888 -msgid "list all relocated users or search for relocated users by pattern" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:893 -msgid "create a new record for a relocated user" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:896 -msgid "delete the record of the relocated user" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:898 -msgid "print information about a relocated user" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:901 -msgid "show the actual value of the configuration option" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:903 -msgid "set a new value for the configuration option" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:905 -msgid "start interactive configuration mode" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:907 -msgid "lists all usable password schemes and password encoding suffixes" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:910 -msgid "show a help overview or help for the given subcommand" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:912 -msgid "show version and copyright information" -msgstr "" - -#. TP: e.g.: [ 0.00%] 21.09 KiB/1.00 GiB -#: VirtualMailManager/cli/subcommands.py:968 -#, python-format -msgid "[%(percent)s%%] %(used)s/%(limit)s" -msgstr "" - -#. TP: used in e.g. 'Domain information' or 'Account information' -#: VirtualMailManager/cli/subcommands.py:974 -msgid "information" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:988 -msgid "Note" -msgstr "" - -#. TP: used in e.g. 'Existing alias addresses' or 'Existing accounts' -#: VirtualMailManager/cli/subcommands.py:1004 -msgid "Existing" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1017 -#: VirtualMailManager/cli/subcommands.py:1069 -#: VirtualMailManager/cli/subcommands.py:1113 -msgid "\tNone" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1022 -msgid "Alias information" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1024 -#, python-format -msgid "\tMail for %s will be redirected to:" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1031 -msgid "Catch-all information" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1033 -#, python-format -msgid "\tMail to unknown local-parts in domain %s will be sent to:" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1041 -msgid "Relocated information" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1043 -#, python-format -msgid "\tUser '%(addr)s' has moved to '%(dest)s'" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1058 -msgid "Matching domains" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1060 -msgid "Existing domains" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1076 -msgid "user accounts" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1079 -msgid "user accounts and aliases" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1080 -msgid "user accounts and relocated users" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1081 -msgid "aliases and relocated users" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1082 -msgid "addresses" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1086 -#, python-format -msgid "Matching %s" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1088 -#, python-format -msgid "Existing %s" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1091 -#, python-format -msgid "Invalid address type for list: '%s'" -msgstr "" - -#. TP: the letters 'u', 'a' and 'r' are abbreviations of user, -#. alias and relocated user -#: VirtualMailManager/cli/subcommands.py:1101 -msgid "u" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1102 -msgid "a" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1103 -msgid "r" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1119 -msgid "Alias domain information" -msgstr "" - -#: VirtualMailManager/cli/subcommands.py:1124 -#, python-format -msgid "" -"\tThe alias domain %(alias)s belongs to:\n" -"\t * %(domain)s" -msgstr "" - -#: VirtualMailManager/common.py:63 -#, python-format -msgid "No such file: '%s'" -msgstr "" - -#: VirtualMailManager/common.py:66 -#, python-format -msgid "File is not executable: '%s'" -msgstr "" - -#: VirtualMailManager/common.py:83 -msgid "GiB" -msgstr "" - -#. TP: abbreviations of gibibyte, tebibyte kibibyte and mebibyte -#: VirtualMailManager/common.py:83 -msgid "TiB" -msgstr "" - -#: VirtualMailManager/common.py:84 -msgid "KiB" -msgstr "" - -#: VirtualMailManager/common.py:84 -msgid "MiB" -msgstr "" - -#. TP: e.g.: '%(size)s %(prefix)s' -> '118.30 MiB' -#: VirtualMailManager/common.py:88 -#, python-format -msgid "%(size)s %(prefix)s" -msgstr "" - -#: VirtualMailManager/common.py:139 -#, python-format -msgid "Invalid transport '%(transport)s' for mailbox format '%(mbfmt)s'." -msgstr "" - -#. TP: [domain default] indicates that a user's setting is the same as -#. configured in the user's domain. -#. e.g.: [ 0.84%] 42/5,000 [domain default] -#: VirtualMailManager/common.py:217 -#, python-format -msgid "%s [domain default]" -msgstr "" - -#: VirtualMailManager/config.py:89 -#, python-format -msgid "Not a boolean: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:127 -#, python-format -msgid "Bad format: '%s' - expected: section.option" -msgstr "" - -#: VirtualMailManager/config.py:378 -#, python-format -msgid "* Section: %s\n" -msgstr "" - -#: VirtualMailManager/config.py:388 VirtualMailManager/config.py:396 -#, python-format -msgid "Check of configuration file %s failed.\n" -msgstr "" - -#: VirtualMailManager/config.py:390 -msgid "Missing options, which have no default value.\n" -msgstr "" - -#: VirtualMailManager/config.py:398 VirtualMailManager/config.py:400 -msgid "Invalid configuration values.\n" -msgstr "" - -#: VirtualMailManager/config.py:439 VirtualMailManager/config.py:523 -#, python-format -msgid "Not a valid Dovecot version: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:445 VirtualMailManager/config.py:480 -#, python-format -msgid "Unsupported database module: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:450 VirtualMailManager/config.py:488 -#, python-format -msgid "Unknown pgsql SSL mode: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:457 VirtualMailManager/config.py:501 -#: VirtualMailManager/maillocation.py:70 -#, python-format -msgid "Unsupported mailbox format: '%s'" -msgstr "" - -#: VirtualMailManager/config.py:473 VirtualMailManager/handler.py:287 -#: VirtualMailManager/handler.py:363 VirtualMailManager/handler.py:368 -#: VirtualMailManager/handler.py:396 -#, python-format -msgid "No such directory: %s" -msgstr "" - -#: VirtualMailManager/config.py:512 -#, python-format -msgid "Not a valid size value: '%s'" -msgstr "" - -#: VirtualMailManager/domain.py:84 -#, python-format -msgid "The domain '%s' is an alias domain." -msgstr "" - -#: VirtualMailManager/domain.py:119 -#, python-format -msgid "" -"There are %(account_count)u accounts, %(alias_count)u aliases and " -"%(relocated_count)u relocated users." -msgstr "" - -#: VirtualMailManager/domain.py:134 -#, python-format -msgid "The domain '%s' already exists." -msgstr "" - -#: VirtualMailManager/domain.py:507 -msgid "The domain name is too long" -msgstr "" - -#: VirtualMailManager/domain.py:509 -#, python-format -msgid "The domain name '%s' is invalid" -msgstr "" - -#: VirtualMailManager/emailaddress.py:73 -#, python-format -msgid "Missing the '@' sign in address: '%s'" -msgstr "" - -#: VirtualMailManager/emailaddress.py:76 -#, python-format -msgid "Too many '@' signs in address: '%s'" -msgstr "" - -#: VirtualMailManager/emailaddress.py:79 -#, python-format -msgid "Missing local-part in address: '%s'" -msgstr "" - -#: VirtualMailManager/emailaddress.py:82 -#, python-format -msgid "Missing domain name in address: '%s'" -msgstr "" - -#: VirtualMailManager/emailaddress.py:145 -#, python-format -msgid "The local-part '%s' is too long." -msgstr "" - -#: VirtualMailManager/emailaddress.py:150 -#, python-format -msgid "The local-part '%(l_part)s' contains invalid characters: %(i_chars)s" -msgstr "" - -#: VirtualMailManager/ext/postconf.py:84 -#, python-format -msgid "" -"The value '%s' does not look like a valid Postfix configuration parameter " -"name." -msgstr "" - -#: VirtualMailManager/handler.py:54 -msgid "an account" -msgstr "" - -#: VirtualMailManager/handler.py:55 -msgid "an alias" -msgstr "" - -#: VirtualMailManager/handler.py:56 -msgid "a relocated user" -msgstr "" - -#: VirtualMailManager/handler.py:82 -msgid "" -"You are not root.\n" -"\tGood bye!\n" -msgstr "" - -#: VirtualMailManager/handler.py:102 -#, python-format -msgid "Could not find '%(cfg_file)s' in: '%(cfg_path)s'" -msgstr "" - -#. TP: Please keep the backticks around the command. `chmod 0600 …` -#: VirtualMailManager/handler.py:114 -#, python-format -msgid "" -"wrong permissions for '%(file)s': %(perms)s\n" -"`chmod 0600 %(file)s` would be great." -msgstr "" - -#: VirtualMailManager/handler.py:134 -#, python-format -msgid "" -"'%(path)s' is not a directory.\n" -"(%(cfg_file)s: section 'misc', option 'base_directory')" -msgstr "" - -#: VirtualMailManager/handler.py:143 -#, python-format -msgid "" -"\n" -"(%(cfg_file)s: section 'bin', option '%(option)s')" -msgstr "" - -#: VirtualMailManager/handler.py:157 VirtualMailManager/handler.py:164 -#, python-format -msgid "Unable to import database module '%s'." -msgstr "" - -#. TP: %(a_type)s will be one of: 'an account', 'an alias' or -#. 'a relocated user' -#: VirtualMailManager/handler.py:243 -#, python-format -msgid "There is already %(a_type)s with the address '%(address)s'." -msgstr "" - -#: VirtualMailManager/handler.py:302 -#, python-format -msgid "'%s' is not a directory." -msgstr "" - -#: VirtualMailManager/handler.py:305 -#, python-format -msgid "The file/directory '%s' already exists." -msgstr "" - -#: VirtualMailManager/handler.py:335 -msgid "Skipped mailbox folders:" -msgstr "" - -#: VirtualMailManager/handler.py:355 -#, python-format -msgid "" -"UID '%(uid)u' and/or GID '%(gid)u' are less than %(min_uid)u/%(min_gid)u." -msgstr "" - -#: VirtualMailManager/handler.py:360 VirtualMailManager/handler.py:393 -#, python-format -msgid "Found \"..\" in domain directory path: %s" -msgstr "" - -#: VirtualMailManager/handler.py:373 -msgid "Detected owner/group mismatch in home directory." -msgstr "" - -#: VirtualMailManager/handler.py:389 -#, python-format -msgid "GID '%(gid)u' is less than '%(min_gid)u'." -msgstr "" - -#: VirtualMailManager/handler.py:400 -#, python-format -msgid "Detected group mismatch in domain directory: %s" -msgstr "" - -#: VirtualMailManager/handler.py:476 VirtualMailManager/handler.py:878 -#, python-format -msgid "Unknown service: '%s'" -msgstr "" - -#: VirtualMailManager/handler.py:601 VirtualMailManager/handler.py:625 -#: VirtualMailManager/handler.py:639 -#, python-format -msgid "The pattern '%s' contains invalid characters." -msgstr "" - -#: VirtualMailManager/handler.py:669 VirtualMailManager/handler.py:732 -#: VirtualMailManager/handler.py:746 VirtualMailManager/handler.py:776 -msgid "Ignored destination addresses:" -msgstr "" - -#: VirtualMailManager/handler.py:674 VirtualMailManager/handler.py:751 -#: VirtualMailManager/handler.py:895 -#, python-format -msgid "The destination account/alias '%s' does not exist." -msgstr "" - -#: VirtualMailManager/handler.py:696 -#, python-format -msgid "" -"The account has been successfully deleted from the database.\n" -" But an error occurred while deleting the following directory:\n" -" '%(directory)s'\n" -" Reason: %(reason)s" -msgstr "" - -#: VirtualMailManager/handler.py:854 -#, python-format -msgid "Could not accept transport: '%s'" -msgstr "" - -#: VirtualMailManager/handler.py:905 VirtualMailManager/relocated.py:106 -#: VirtualMailManager/relocated.py:113 -#, python-format -msgid "The relocated user '%s' does not exist." -msgstr "" - -#: VirtualMailManager/mailbox.py:260 -#, python-format -msgid "Failed to create mailboxes: %r\n" -msgstr "" - -#: VirtualMailManager/maillocation.py:74 -msgid "Empty directory name" -msgstr "" - -#: VirtualMailManager/maillocation.py:76 -#, python-format -msgid "Directory name is too long: '%s'" -msgstr "" - -#: VirtualMailManager/password.py:389 -#, python-format -msgid "Unsupported password scheme: '%s'" -msgstr "" - -#: VirtualMailManager/password.py:392 -#, python-format -msgid "The password scheme '%(scheme)s' requires Dovecot >= v%(version)s." -msgstr "" - -#: VirtualMailManager/password.py:398 -msgid "Encoding suffixes for password schemes require Dovecot >= v1.1.alpha1." -msgstr "" - -#: VirtualMailManager/password.py:401 -#, python-format -msgid "Unsupported password encoding: '%s'" -msgstr "" - -#: VirtualMailManager/relocated.py:62 VirtualMailManager/relocated.py:76 -msgid "The destination address' domain name must not be localhost." -msgstr "" - -#: VirtualMailManager/relocated.py:79 -msgid "Address and destination are identical." -msgstr "" - -#: VirtualMailManager/relocated.py:83 -#, python-format -msgid "The relocated user '%s' already exists." -msgstr "" diff -r 659c4476c57c -r b678a1c43027 postfix/pgsql-relocated_maps.cf --- a/postfix/pgsql-relocated_maps.cf Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS -# -# The hosts that Postfix will try to connect to and query from. -hosts = localhost - -# The user name and password to log into the pgsql server. -user = postfix -password = some_password - -# The database name on the servers. -dbname = mailsys - -# The SQL query template used to search the database -query = SELECT destination FROM postfix_relocated_map('%u', '%d') diff -r 659c4476c57c -r b678a1c43027 postfix/pgsql-smtpd_sender_login_maps.cf --- a/postfix/pgsql-smtpd_sender_login_maps.cf Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS -# -# The hosts that Postfix will try to connect to and query from. -hosts = localhost - -# The user name and password to log into the pgsql server. -user = postfix -password = some_password - -# The database name on the servers. -dbname = mailsys - -# XXX see create_optional_types_and_functions.pgsql -# * line 9: type sender_login -# * line 26: function postfix_smtpd_sender_login_map + comment above -# -# The SQL query template used to search the database -query = SELECT login FROM postfix_smtpd_sender_login_map('%u', '%d') diff -r 659c4476c57c -r b678a1c43027 postfix/pgsql-transport_maps.cf --- a/postfix/pgsql-transport_maps.cf Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS -# -# The hosts that Postfix will try to connect to and query from. -hosts = localhost - -# The user name and password to log into the pgsql server. -user = postfix -password = some_password - -# The database name on the servers. -dbname = mailsys - -# The SQL query template used to search the database -query = SELECT transport FROM postfix_transport_map('%u', '%d') diff -r 659c4476c57c -r b678a1c43027 postfix/pgsql-virtual_alias_maps.cf --- a/postfix/pgsql-virtual_alias_maps.cf Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS -# -# The hosts that Postfix will try to connect to and query from. -hosts = localhost - -# The user name and password to log into the pgsql server. -user = postfix -password = some_password - -# The database name on the servers. -dbname = mailsys - -# The SQL query template used to search the database -query = SELECT destination FROM postfix_virtual_alias_map('%u', '%d') diff -r 659c4476c57c -r b678a1c43027 postfix/pgsql-virtual_gid_maps.cf --- a/postfix/pgsql-virtual_gid_maps.cf Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS -# -# The hosts that Postfix will try to connect to and query from. -hosts = localhost - -# The user name and password to log into the pgsql server. -user = postfix -password = some_password - -# The database name on the servers. -dbname = mailsys - -# The SQL query template used to search the database -query = SELECT gid FROM postfix_gid WHERE domainname='%d' diff -r 659c4476c57c -r b678a1c43027 postfix/pgsql-virtual_mailbox_domains.cf --- a/postfix/pgsql-virtual_mailbox_domains.cf Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS -# -# The hosts that Postfix will try to connect to and query from. -hosts = localhost - -# The user name and password to log into the pgsql server. -user = postfix -password = some_password - -# The database name on the servers. -dbname = mailsys - -# The SQL query template used to search the database -query = SELECT gid FROM postfix_gid WHERE domainname='%s' diff -r 659c4476c57c -r b678a1c43027 postfix/pgsql-virtual_mailbox_maps.cf --- a/postfix/pgsql-virtual_mailbox_maps.cf Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS -# -# The hosts that Postfix will try to connect to and query from. -hosts = localhost - -# The user name and password to log into the pgsql server. -user = postfix -password = some_password - -# The database name on the servers. -dbname = mailsys - -# The SQL query template used to search the database -query = SELECT maildir FROM postfix_virtual_mailbox_map('%u', '%d') diff -r 659c4476c57c -r b678a1c43027 postfix/pgsql-virtual_uid_maps.cf --- a/postfix/pgsql-virtual_uid_maps.cf Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -# All parameters are described in pgsql_table(5) / PGSQL PARAMETERS -# -# The hosts that Postfix will try to connect to and query from. -hosts = localhost - -# The user name and password to log into the pgsql server. -user = postfix -password = some_password - -# The database name on the servers. -dbname = mailsys - -# The SQL query template used to search the database -query = SELECT uid FROM postfix_virtual_uid_map('%u', '%d') diff -r 659c4476c57c -r b678a1c43027 setup.cfg --- a/setup.cfg Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -[install] -compile = 1 -optimize = 1 - -[sdist] -formats = bztar diff -r 659c4476c57c -r b678a1c43027 setup.py --- a/setup.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# Copyright 2007 - 2014, Pascal Volk -# See COPYING for distribution information. - -import os -from distutils.core import setup -from distutils.dist import DistributionMetadata - -VERSION = '0.6.2' - -descr = 'Tool to manage mail domains/accounts/aliases for Dovecot and Postfix' -long_description = """ -vmm, a virtual mail manager, is a command line tool for -administrators/postmasters to manage (alias-)domains, accounts, -aliases and relocated users. -It is designed for Dovecot and Postfix with a PostgreSQL backend. -""" -packages = [ - 'VirtualMailManager', - 'VirtualMailManager.cli', - 'VirtualMailManager.ext', - 'VirtualMailManager.pycompat', -] -# http://pypi.python.org/pypi?%3Aaction=list_classifiers -classifiers = ['Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: BSD License', - 'Natural Language :: Dutch', - 'Natural Language :: English', - 'Natural Language :: Finnish', - 'Natural Language :: French', - 'Natural Language :: German', - 'Natural Language :: Vietnamese', - 'Operating System :: POSIX', - 'Operating System :: POSIX :: BSD', - 'Operating System :: POSIX :: Linux', - 'Operating System :: POSIX :: Other', - 'Programming Language :: Python', - 'Programming Language :: Python :: 2', - 'Topic :: Communications :: Email', - 'Topic :: System :: Systems Administration', - 'Topic :: Utilities'] - -# sucessfuly tested on: -platforms = ['freebsd7', 'linux2', 'openbsd4'] - -# remove existing MANIFEST -if os.path.exists('MANIFEST'): - os.remove('MANIFEST') - -setup_args = {'name': 'VirtualMailManager', - 'version': VERSION, - 'description': descr, - 'long_description': long_description, - 'packages': packages, - 'author': 'Pascal Volk', - 'author_email': 'user+vmm@localhost.localdomain.org', - 'license': 'BSD License', - 'url': 'http://vmm.localdomain.org/', - 'download_url':'http://sf.net/projects/vmm/files/', - 'platforms': platforms, - 'classifiers': classifiers} - -if 'requires' in DistributionMetadata._METHOD_BASENAMES: - setup_args['requires'] = ['psycopg2 (>=2.0)', 'pyPgSQL (>=2.5.1)'] - -setup(**setup_args) diff -r 659c4476c57c -r b678a1c43027 update_config.py --- a/update_config.py Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,178 +0,0 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- -# Copyright (c) 2008 - 2014, Pascal Volk -# See COPYING for distribution information. - -import os -os.sys.path.remove(os.sys.path[0]) -from time import time -from ConfigParser import ConfigParser -from shutil import copy2 - -pre_060 = False - -try: - from VirtualMailManager.constants.VERSION import VERSION - pre_060 = True -except ImportError: - try: - from VirtualMailManager.constants import VERSION - except ImportError: - os.sys.stderr.write('error: no vmm version information found\n') - raise SystemExit(2) - -# we have to remove the old CamelCase files -if pre_060: - import VirtualMailManager - vmm_inst_dir = os.path.dirname(VirtualMailManager.__file__) - tmp_info = open('/tmp/vmm_inst_dir', 'w') - tmp_info.write(vmm_inst_dir) - tmp_info.close() - -try: - import psycopg2 -except ImportError: - has_psycopg2 = False -else: - has_psycopg2 = True - - -def get_config_file(): - f = None - for d in ('/root', '/usr/local/etc', '/etc'): - tmp = os.path.join(d, 'vmm.cfg') - if os.path.isfile(tmp): - f = tmp - break - if f: - return f - else: - os.sys.stderr.write('error: vmm.cfg not found\n') - raise SystemExit(2) - - -def update(cp): - if VERSION == '0.5.2': - upd_052(cp) - elif VERSION in ('0.6.0', '0.6.1'): - os.sys.stdout.write('info: vmm.cfg: nothing to do for version %s\n' % - VERSION) - return - else: - os.sys.stderr.write('error: the version %s is not supported by this ' - 'script\n' % VERSION) - raise SystemExit(3) - - -def get_cfg_parser(cf): - fh = open(cf, 'r') - cp = ConfigParser() - cp.readfp(fh) - fh.close() - return cp - - -def update_cfg_file(cp, cf): - copy2(cf, cf + '.bak.' + str(time())) - fh = open(cf, 'w') - cp.write(fh) - fh.close() - - -def add_sections(cp, sections): - for section in sections: - if not cp.has_section(section): - cp.add_section(section) - - -def move_option(cp, src, dst): - ds, do = dst.split('.') - if not cp.has_option(ds, do): - ss, so = src.split('.') - cp.set(ds, do, cp.get(ss, so)) - cp.remove_option(ss, so) - sect_opt.append((dst, 'R')) - - -def add_option(cp, dst, val): - ds, do = dst.split('.') - if not cp.has_option(ds, do): - cp.set(ds, do, val) - sect_opt.append((dst, 'N')) - - -def set_dovecot_version(cp): - if len(os.sys.argv) > 1: - dovecot_version = os.sys.argv[1].strip() - if not dovecot_version: - dovecot_version = '1.2.11' - else: - dovecot_version = '1.2.11' - cp.set('misc', 'dovecot_version', dovecot_version) - sect_opt.append(('misc.dovecot_version', 'M')) - - -def get_option(cp, src): - ss, so = src.split('.') - return cp.get(ss, so) - - -def upd_052(cp): - global had_config - global had_gid_mail - - had_config = cp.remove_section('config') - had_gid_mail = cp.remove_option('misc', 'gid_mail') - add_sections(cp, ('domain', 'account', 'mailbox')) - if cp.has_section('domdir'): - for src, dst in (('domdir.mode', 'domain.directory_mode'), - ('domdir.delete', 'domain.delete_directory'), - ('domdir.base', 'misc.base_directory')): - move_option(cp, src, dst) - cp.remove_section('domdir') - if cp.has_section('services'): - for service in cp.options('services'): - move_option(cp, 'services.%s' % service, 'domain.%s' % service) - cp.remove_section('services') - for src, dst in (('maildir.mode', 'account.directory_mode'), - ('maildir.diskusage', 'account.disk_usage'), - ('maildir.delete', 'account.delete_directory'), - ('maildir.folders', 'mailbox.folders'), - ('maildir.name', 'mailbox.root'), - ('misc.forcedel', 'domain.force_deletion'), - ('misc.transport', 'domain.transport'), - ('misc.passwdscheme', 'misc.password_scheme'), - ('misc.dovecotvers', 'misc.dovecot_version')): - move_option(cp, src, dst) - cp.remove_section('maildir') - if not has_psycopg2: - add_option(cp, 'database.module', 'pyPgSQL') - set_dovecot_version(cp) - - -# def main(): -if __name__ == '__main__': - sect_opt = [] - had_config = False - had_gid_mail = False - cf = get_config_file() - cp = get_cfg_parser(cf) - update(cp) - if len(sect_opt): - update_cfg_file(cp, cf) - sect_opt.sort() - print 'Please have a look at your configuration: %s' % cf - print 'This are your Modified/Renamed/New settings:' - for s_o, st in sect_opt: - print '%s %s = %s' % (st, s_o, get_option(cp, s_o)) - if had_config: - print '\nRemoved section "config" with option "done" (obsolte)' - if had_gid_mail: - print '\nRemoved option "gid_mail" from section "misc" (obsolte)\n' - os.sys.exit(0) - if had_config or had_gid_mail: - update_cfg_file(cp, cf) - if had_config: - print '\nRemoved section "config" with option "done" (obsolte)' - if had_gid_mail: - print '\nRemoved option "gid_mail" from section "misc" (obsolte)\n' diff -r 659c4476c57c -r b678a1c43027 upgrade.sh --- a/upgrade.sh Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,93 +0,0 @@ -#!/bin/sh -# -# Upgrade script for the Virtual Mail Manager -# run: ./upgrade.sh - -LANG=C -PATH=/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin -PREFIX=/usr/local - -DOVECOT_VERS=$(dovecot --version | awk '{print $1}') -LOCALE_DIR=${PREFIX}/share/locale -DOC_DIR=${PREFIX}/share/doc/vmm -if [ ${PREFIX} = "/usr" ]; then - MANDIR=${PREFIX}/share/man -else - MANDIR=${PREFIX}/man -fi -DOCS="ChangeLog Configure.Dovecot_2 COPYING INSTALL NEWS README" - -INSTALL_OPTS="-g 0 -o 0 -p" - -if [ $(id -u) -ne 0 ]; then - echo "Run this script as root." - exit 1 -fi - -# update config file before installing the new files. -./update_config.py ${DOVECOT_VERS:-'1.2.11'} -rv=$? -if [ $rv -eq 2 ]; then - echo "please run the install.sh script" - exit 1 -elif [ $rv -eq 3 ]; then - echo "please read the upgrade instructions at http://vmm.localdomain.org/" - exit 1 -elif [ $rv -ne 0 ]; then - echo "Sorry, something went wrong. Please file a bug at:" - echo "https://bitbucket.org/pvo/vmm/issues" - exit 1 -fi - -# remove old CamelCase files -if [ -f /tmp/vmm_inst_dir ] ; then - rm -rf `cat /tmp/vmm_inst_dir` - rm -f /tmp/vmm_inst_dir -fi - -python setup.py -q install --force --prefix ${PREFIX} -python setup.py clean --all >/dev/null - -install -m 0700 ${INSTALL_OPTS} vmm ${PREFIX}/sbin - -[ -d ${LOCALE_DIR} ] || mkdir -m 0755 -p ${LOCALE_DIR} -cd po -for po in $(ls -1 *.po); do - lang=$(basename ${po} .po) - ddir=${LOCALE_DIR}/${lang}/LC_MESSAGES - [ -d ${ddir} ] || mkdir -m 0755 -p ${ddir} - msgfmt -o ${LOCALE_DIR}/${lang}/LC_MESSAGES/vmm.mo ${po} -done -cd - >/dev/null - -# install manual pages -cd man -[ -d ${MANDIR}/man1 ] || mkdir -m 0755 -p ${MANDIR}/man1 -install -m 0644 ${INSTALL_OPTS} man1/vmm.1 ${MANDIR}/man1 - -[ -d ${MANDIR}/man5 ] || mkdir -m 0755 -p ${MANDIR}/man5 -install -m 0644 ${INSTALL_OPTS} man5/vmm.cfg.5 ${MANDIR}/man5 - -for l in $(find . -maxdepth 1 -mindepth 1 -type d \! -name man\?) -do - for s in man1 man5; do - [ -d ${MANDIR}/${l}/${s} ] || mkdir -m 0755 -p ${MANDIR}/${l}/${s} - done - if [ -f ${l}/man1/vmm.1 ]; then - install -m 0644 ${INSTALL_OPTS} ${l}/man1/vmm.1 ${MANDIR}/${l}/man1 - fi - if [ -f ${l}/man5/vmm.cfg.5 ]; then - install -m 0644 ${INSTALL_OPTS} ${l}/man5/vmm.cfg.5 ${MANDIR}/${l}/man5 - fi -done -cd - >/dev/null - -[ -d ${DOC_DIR} ] || mkdir -m 0755 -p ${DOC_DIR} -for DOC in ${DOCS}; do - install -m 0644 ${INSTALL_OPTS} ${DOC} ${DOC_DIR} -done - -[ -d ${DOC_DIR}/examples ] || mkdir -m 0755 -p ${DOC_DIR}/examples -install -m 0644 ${INSTALL_OPTS} postfix/pgsql-*.cf ${DOC_DIR}/examples -install -m 0644 ${INSTALL_OPTS} vmm.cfg ${DOC_DIR}/examples - diff -r 659c4476c57c -r b678a1c43027 vmm --- a/vmm Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -#!/usr/bin/env python -# -*- coding: UTF-8 -*- -# Copyright 2007 - 2014, Pascal Volk -# See COPYING for distribution information. - -"""This is the vmm main script.""" - -import sys - -if __name__ == '__main__': - # replace the script's cwd (/usr/local/sbin) with our module dir - # (the location of the VirtualMailManager directory) - if it is - # not in sys.path - #sys.path[0] = '/usr/local/lib/vmm' - # Otherwise just remove /usr/local/sbin from sys.path - sys.path.remove(sys.path[0]) - from VirtualMailManager.cli.main import run - sys.exit(run(sys.argv)) diff -r 659c4476c57c -r b678a1c43027 vmm.cfg --- a/vmm.cfg Mon Mar 24 19:22:04 2014 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -# This is the vmm (a virtual mail manager) configuration file. -# default location: /usr/local/etc/vmm.cfg -# - -# -# Database settings -# -[database] -; The Python PostgreSQL database adapter module to be used (String) -; Supported modules are: -; * psycopg2 -; * pyPgSQL -module = psycopg2 -; Hostname or IP address of the database server (String) -host = localhost -; The TCP port, on which the database server is listening for connections (Int) -port = 5432 -; SSL mode for the database connection (String) -; Possible values are: -; * disabled -; * allow -; * prefer (default) -; * require -; * verify-ca (PostgreSQL >= 8.4) -; * verify-full (PostgreSQL >= 8.4) -sslmode = prefer -; Database user name (String) -user = vmm -; Database password (String) -pass = dbpassword -; Database name (String) -name = mailsys - -# -# mailbox settings -# -[mailbox] -; The mailbox format to be used for user's mailboxes. (String) -; Depending on the used Dovecot version there are up to 3 supported formats: -; * maildir - since Dovecot v1.0.0 -; * mdbox - since Dovecot v2.0.beta5 -; * sdbox - since Dovecot v2.0.rc3 -format = maildir -; A colon separated list of mailbox names, that should be created (String) -; e.g.: folders = Drafts:Sent:Templates:Trash:Lists.Dovecot:Lists.Postfix -folders = Drafts:Sent:Templates:Trash -; Name of the mailbox root directory in a user's home. (String) -; Usually used names (format: name): -; * maildir: Maildir -; * mdbox: mdbox -; * sdbox: sdbox -root = Maildir -; Set to true if the mailboxes from the folders option should be listed in -; the subscriptions file. (Boolean) -subscribe = true - -# -# Domain settings -# -[domain] -; Should vmm create the postmaster account when a new domain is created? -; (Boolean) -auto_postmaster = true -; Delete domain directory recursive when deleting a domain? (Boolean) -delete_directory = false -; Permissions for domain directories (Int) -; octal 0770 -> decimal 504 -directory_mode = 504 -; Force deletion of accounts and aliases when deleting a domain (Boolean) -force_deletion = false -; -; The service settings will be evaluated and applied when a domain is -; created. The service settings of the domain will be applied when you -; create a new account. -; Use the subcommand domainservices to modify a domain's service settings. -; Or userservices in order to update the service setting of an account. -; Allow smtp by default? (Boolean) -smtp = true -; Allow pop3 by default? (Boolean) -pop3 = true -; Allow imap by default? (Boolean) -imap = true -; Allow managesieve by default? (Boolean) -sieve = true -; -; The quota_* settings will be evaluated and applied when a domain is -; created. The domain's quota_* settings will be applied when an account -; is added to a domain. -; Use the subcommand domainquota to modify a domain's quota limits. -; Or userquota in order to update an account's quota limits. -; Quota limit in bytes. 0 means unlimited (String) -; The value can have one of the suffixes: -; * b: bytes -; * k: kilobytes -; * M: megabytes -; * G: gigabytes -; 1024 is the same as 1024b or 1k -quota_bytes = 0 -; Quota limit in number of messages. 0 means unlimited (Int) -quota_messages = 0 -; -; The transport setting will be evaluated and applied when a domain is -; created. The domain's transport setting will be applied when an account -; is added to a domain. -; Use the subcommand domaintransport to modify the transport of a domain. -; Or usertransport in order to update an account's transport setting. -; -; With Dovecot >= v2.0.0 it's strongly recommended that you use Dovecot's -; lmtp instead of the dovecot-lda. -;transport = lmtp:unix:private/dovecot-lmtp -; default transport for domains and accounts (String) -transport = dovecot: - -# -# Account settings -# -[account] -; Delete the user's home directory recursive when deleting an account? (Boolean) -delete_directory = false -; Permissions for the user's home directory and mail directories (Int) -; octal 0700 -> decimal 448 -directory_mode = 448 -; Display disk usage in account info by default? (Boolean) -disk_usage = false -; Should vmm generate a random password when no password was given for the -; useradd subcommand? (Boolean) -random_password = false -; How many characters to include in the generated passwords? (Int) -password_length = 8 - -# -# external binaries -# -[bin] -; location of dovecotpw (Dovecot v1) or doveadm (Dovecot v2) (String) -dovecotpw = /usr/sbin/dovecotpw -; location of disk usage (String) -du = /usr/bin/du -; location of postconf (String) -postconf = /usr/sbin/postconf - -# -# misc settings -# -[misc] -; The base directory for all domains/accounts (String) -base_directory = /srv/mail -; Number of encryption rounds for the password_scheme BLF-CRYPT (Int) -crypt_blowfish_rounds = 5 -; Number of encryption rounds for the password_scheme SHA256-CRYPT (Int) -crypt_sha256_rounds = 5000 -; Number of encryption rounds for the password_scheme SHA512-CRYPT (Int) -crypt_sha512_rounds = 5000 -; the version number from `dovecot --version` (String) -; e.g. 1.2.17, 2.0.21, 2.1.9 or 2.2.beta1 -dovecot_version = 2.1.9 -; NOTE: When using other password schemes than PLAIN or CRAM-MD5, you -; have to remove `cram-md5' from the auth_mechanisms setting in -; dovecot/conf.d/10-auth.conf. -; Password scheme to use (see also: ´vmm listpwschemes`) (String) -password_scheme = CRAM-MD5 -