diff --git a/INSTALL b/INSTALL index a6fbf2a..a99301f 100644 --- a/INSTALL +++ b/INSTALL @@ -9,10 +9,11 @@ OVERVIEW: 3 - configuration file 4 - create a suid cgi wrapper 5 - [optional] configure access control (http authentication) - 6 - css stylesheet file - 7 - final test - 8 - troubleshooting - 9 - report problems + 6 - [optional] configure multi domain support + 7 - css stylesheet file + 8 - final test + 9 - troubleshooting + 10 - report problems ------------------------------------------------------------------------------ @@ -123,14 +124,29 @@ OVERVIEW: Again, see the ApacheWeek article for details. -6. Copy the stylesheet file (/usr/local/share/ezmlm-web/css/default.css) +6. You may skip this step if you manage only one directory containing mailing + lists. For more than one domain or multiple user directories you should + follow the instructions below. BEWARE: this is an advanced setting. + + 1) copy examples/multidomain.conf.dist to /etc/ezmlm-web/multidomain.conf + 2) add your mailing list parent directories to this file + 3) uncomment the respective line in your ezmlmwebrc file + + The web interface should now show a "Change domain" link in the navigation + bar to the left. + + Direct links to a specifc domain use the following format: + http://BASE_URL/ezmlm-web?domain=foo + + +7. Copy the stylesheet file (/usr/local/share/ezmlm-web/css/default.css) to a location of your choice. It has to be accessible by an URL - maybe a place like "/var/www/ezmlm-web.css" could be appropriate. Now you may have to change the "HTML_CSS_FILE" setting in your ezmlmwebrc file. This value is a URL - not the local filename. -7. Test the installation with your favourite web browser. You should be +8. Test the installation with your favourite web browser. You should be asked for a username and password (supplied in 6.2) and then be presented with a screen entitled "EZ Mailing List Manger". You can then try to create and edit mailing lists ... Have Fun :) @@ -139,11 +155,11 @@ OVERVIEW: option correctly in ezmlmwebrc. Check it again. -8. If anything failes - take a look at the web server's error log +9. If anything failes - take a look at the web server's error log (e.g. /var/log/apache/error.log). -9. If the error log of your web server did not help you to solve your problem: +10. If the error log of your web server did not help you to solve your problem: - take a look at https://systemausfall.org/toolforge/ezmlm-web - send me an email: ezmlm-web@sumpfralle.de - subscribe to the mailinglist: ezmlm-web-subscribe@lists.systemausfall.org diff --git a/changelog b/changelog index 0c4225b..a310519 100644 --- a/changelog +++ b/changelog @@ -1,12 +1,13 @@ Version 3.2 - 04/14/02006 * support for encrypted mailing lists (https://systemausfall.org/toolforge/gpgpy-ezmlm/) + * support for multi-domain setups * detect preferred interface language * user-specific interface language selection * handling of empty settings for ezmlm-idx 5.0 fixed (closes #21) * script for creating binary suid wrappers added * bug in MySQL support fixed - * treatment of the special character "dot" in listname and list address fixed + * handling of the special character "dot" in listname and list address fixed * the formerly required module "Encode" is now optional * support for listing of subscription log diff --git a/examples/ezmlmwebrc.dist b/examples/ezmlmwebrc.dist index c9a24cf..577ffae 100644 --- a/examples/ezmlmwebrc.dist +++ b/examples/ezmlmwebrc.dist @@ -13,6 +13,17 @@ # BEWARE: the (resulting) path MUST be absolute (starting with a slash)! $LIST_DIR = "$HOME_DIR/lists"; +# Multi-Domain-Support +# This is a quite advanced setting for special installations. +# Most people should just ignore it. +# Anyway - if you want to control more than one directory containing +# different lists, then you should: +# 1) copy examples/multidomain.conf.dist to /etc/ezmlm-web/multidomain.conf +# 2) adjust /etc/ezmlm-web/multidomain.conf to your setup +# 3) uncomment the following line +# 4) make sure that your multi domain settings are not overriden below +#warn "multidomain.conf failed" unless (defined do "/etc/ezmlm-web/multidomain.conf"); + # Where do we store the dotqmail files of this user? # (defaults to the home directory of the executing user) # You will have to change this value, if you use a multi domain diff --git a/examples/multidomain.conf.dist b/examples/multidomain.conf.dist new file mode 100644 index 0000000..e76e3ce --- /dev/null +++ b/examples/multidomain.conf.dist @@ -0,0 +1,55 @@ +# This is a configuration file for ezmlm-web setups with more than one +# mailing list directory. +# +# If you want to use multi-domain support, then you should somehow know +# what you are doing. You have been warned! ;) +# +# Usually you just need to adjust the $DOMAIN setting below. +# Use the existing example as a template. +# +# If your setup is a little bit more exotic, then you can change the code, too. +# In the end, the setting $LIST_DIR should either be an empty string or +# the path of a mailing list directory. You may also want to take care for the +# $DOTQMAIL_DIR and $MAILDOMAIN settings. +# +# BEWARE: you may not define new variables as - otherwise they could collide +# with the names of variables of the ezmlm-web program. +# + + +{ + # we do not want to spoil our namespace - but we need CGI input + use CGI (); + $CURRENT_DOMAIN = new CGI->param('domain'); +}; + +# domain names may not contain any special characters +# you must define at least "name" and "list_dir" for each domain +%DOMAINS = ( + foo => { + name => "Example Domain Foo", + list_dir => "/data/lists/foo", + dot_dir => "/data/lists/foo", + mail_domain => "lists.foo.org", + }, + bar => { + name => "Example Domain Bar", + list_dir => "/data/lists/bar", + dot_dir => "/data/lists/bar", + mail_domain => "lists.bar.org", + }, +); + + +# this simple code defines $LIST_DIR and $DOTQMAILDIR in a sane way +if (defined($CURRENT_DOMAIN) && defined($DOMAINS{$CURRENT_DOMAIN})) { + $LIST_DIR = $DOMAINS{$CURRENT_DOMAIN}{'list_dir'} + if (defined $DOMAINS{$CURRENT_DOMAIN}{'list_dir'}); + $DOTQMAIL_DIR = $DOMAINS{$CURRENT_DOMAIN}{'dot_dir'} + if (defined $DOMAINS{$CURRENT_DOMAIN}{'dot_dir'}); + $MAIL_DOMAIN = $DOMAINS{$CURRENT_DOMAIN}{'mail_domain'} + if (defined $DOMAINS{$CURRENT_DOMAIN}{'mail_domain'}); +} else { + $LIST_DIR = ''; +} + diff --git a/ezmlm-web.cgi b/ezmlm-web.cgi index 6b1b96c..38f529e 100755 --- a/ezmlm-web.cgi +++ b/ezmlm-web.cgi @@ -22,7 +22,8 @@ use CGI; use IO::File; use POSIX; use English; -use Time::localtime; +# TODO: uncomment it later +use Time::localtime (); # gettext support is optional my $GETTEXT_SUPPORT = 1; @@ -79,6 +80,8 @@ use vars qw[$HTML_CSS_FILE $TEMPLATE_DIR $LANGUAGE_DIR $HTML_LANGUAGE]; use vars qw[$DEFAULT_HOST]; # some settings for encrypted mailing lists use vars qw[$GPG_SUPPORT]; +# settings for multi-domain setups +use vars qw[%DOMAINS $CURRENT_DOMAIN]; # some deprecated configuration settings - they have to be announced # otherwise old configuration files would break @@ -106,7 +109,15 @@ if (defined($opt_C)) { } else { &fatal_error("Unable to find config file"); } -do $config_file; +unless (my $return = do $config_file) { + if ($@) { + &fatal_error("Failed to parse the config file ($config_file): $@"); + } elsif (!defined $return) { + &fatal_error("Failed to read the config file ($config_file): $!"); + } else { + # the last statement of the config file return False -> this is ok + } +} ####### validate configuration and apply some default settings ########## @@ -162,8 +173,13 @@ my $action = $q->param('action'); # This is where we decide what to do, depending on the form state and the # users chosen course of action ... # TODO: unify all these "is list param set?" checks ... -# check permissions -unless (&check_permission_for_action()) { +if (%DOMAINS && (!defined($CURRENT_DOMAIN) || ($CURRENT_DOMAIN eq '') + || ($action eq 'domain_select'))) { + # domain support is enabled, but no domain is selected + $pagename = 'domain_select'; + # undef the currently selected domain + undef $CURRENT_DOMAIN; +} elsif (!&check_permission_for_action()) { $pagename = 'list_select'; $error = 'Forbidden'; } elsif ($action eq '' || $action eq 'list_select') { @@ -423,6 +439,8 @@ unless (&check_permission_for_action()) { # set default action, if there is no list available and the user is # allowed to create a new one if (((!defined($action)) || ($action eq '')) + && ((%DOMAINS && defined($CURRENT_DOMAIN) and ($CURRENT_DOMAIN ne '')) + || (!%DOMAINS)) && (&webauth_create_allowed()) && ($pagedata->getValue('Data.Lists.0','') eq '')) { $pagename = 'list_create'; @@ -524,7 +542,7 @@ sub load_interface_language { unless (&check_interface_language($HTML_LANGUAGE)); # first: load default language - in case some translations are incomplete - $data->readFile("$LANGUAGE_DIR/$HTML_LANGUAGE" . ".hdf"); + $data->readFile("$LANGUAGE_DIR/$config_language" . ".hdf"); # check for preferred browser language, if the box was not initialized yet my $prefLang = &get_browser_language(); @@ -583,10 +601,38 @@ sub get_browser_language { # --------------------------------------------------------------------------- +sub set_pagedata_domains { + + my ($domain_name); + + # multi-domain setup? + if (defined($CURRENT_DOMAIN)) { + $pagedata->setValue("Config.UI.LinkAttrs.domain", $CURRENT_DOMAIN); + $pagedata->setValue("Data.CurrentDomain", $CURRENT_DOMAIN); + $pagedata->setValue("Data.CurrentDomain.Description", + $DOMAINS{$CURRENT_DOMAIN}{name}); + } + + foreach $domain_name (keys %DOMAINS) { + $pagedata->setValue("Data.Domains.$domain_name", + $DOMAINS{$domain_name}{'name'}); + } +} + +# --------------------------------------------------------------------------- + sub set_pagedata_list_of_lists { my (@files, $i, $num); + # for a multi-domain setup there are no lists available if no domain + # is selected + return (0==0) if (%DOMAINS && + (!defined($CURRENT_DOMAIN) || ($CURRENT_DOMAIN eq ''))); + + # undefined $LIST_DIR? + return (0==0) if (!defined($LIST_DIR) || ($LIST_DIR eq '')); + # Read the list directory for mailing lists. return (0==0) unless (opendir DIR, $LIST_DIR); @@ -612,6 +658,9 @@ sub set_pagedata { # read available list of lists &set_pagedata_list_of_lists(); + # multi domain support? + &set_pagedata_domains() if (%DOMAINS); + # username and hostname # Work out if this user has a virtual host and set input accordingly ... if (-e "$QMAIL_BASE/virtualdomains") { @@ -2002,6 +2051,11 @@ sub webauth { sub webauth_create_allowed { + # for a multi-domain setup we disallow list creation until a domain + # is selected + return (1==0) if (%DOMAINS && + (!defined($CURRENT_DOMAIN) || ($CURRENT_DOMAIN eq ''))); + # Check if we were called with the deprecated argument "-c" (allow to create lists) return (0==0) if (defined($opt_c)); diff --git a/lang/de.hdf b/lang/de.hdf index 887d804..b109418 100644 --- a/lang/de.hdf +++ b/lang/de.hdf @@ -26,7 +26,8 @@ Lang { Properties = Eigenschaften von Language = Sprache Help = Hilfe (extern) - SubscribeLog = Subscriber's log + SubscribeLog = Einschreibungen + DomainSelect = Choose a domain } Title { ConfigMain = Listeneinstellungen @@ -46,12 +47,13 @@ Lang { ListDelete = Liste löschen FileSelect = Auswählen eines Textbausteins FileEdit = Bearbeitung des Textbausteins - SubscribeLog = Subscription events + SubscribeLog = Einschreibungsereignisse GnupgConvert = Verschlüsselung GnupgPublic = Öffentliche Schlüssel GnupgSecret = Private Schlüssel GnupgGenerate = Erzeugen eines Schlüssels GnupgOptions = Verschlüsselungseinstellungen + DomainSelect = Choose a domain } Buttons { Create = Erzeuge die Liste @@ -112,7 +114,7 @@ Lang { RequiresIDX5 = Diese Aktion erfordert ezmlm-idx in der Version 5.0 ResetFileIsDefault = Dieser Textbaustein ist keine angepasste Variante und kann somit nicht zurückgesetzt werden. ResetFile = Der angepasste Textbaustein konnte nicht entfernt werden. - LogFile = Reading of log file failed. + LogFile = Das Lesen der Protokoll-Datei schlug fehl. GnupgNoKeyFile = Es wurde keine Datei zum Hochladen ausgewählt! GnupgDelKey = Mindestens ein Schlüssel konnte nicht gelöscht werden! GnupgNoKeySelected = Es wurde kein Schlüssel ausgewählt! @@ -225,6 +227,7 @@ Lang { GnupgKeySize = Schlüssellänge (in Bytes) GnupgKeyExpires = Verfallsdatum (in Jahren) Never = nie + NoDomainsAvailable = No domains are available. } Introduction { ConfigAdmin = Fern-AdministratorInnen sind (per Voreinstellung) auch ModeratorInnen für die Einschreibung und für eingesandte Mails. Sie können berechtigt sein, per Mail Nutzer ein- und auszutragen, sowie Textbausteine zu verändern. @@ -268,12 +271,13 @@ Lang { TextFileReset = Auf die Vorgabe zurücksetzen TextFileInfo = Nützliche Platzhalter AvailableLists = Verfügbare Listen - SubscribeLog = Events + SubscribeLog = Ereignisse GnupgConvert = Verschlüsselungsunterstützung GnupgPublicKeys = Öffentliche Schlüssel dieser Liste GnupgSecretKeys = Private Schlüssel dieser Liste GnupgKeyImport = Schlüssel importieren GnupgGenerateKey = Schlüssel der Liste erzeugen GnupgOptions = Verschlüsselungseinstellungen + AvailableDomains = Available domains } } diff --git a/lang/en.hdf b/lang/en.hdf index 3c2a7aa..01bfb25 100644 --- a/lang/en.hdf +++ b/lang/en.hdf @@ -29,6 +29,7 @@ Lang { Language = Language Help = Help (external) SubscribeLog = Subscriber's log + DomainSelect = Choose a domain } @@ -56,6 +57,7 @@ Lang { GnupgSecret = Secret keys GnupgGenerate = Generate a new keypair GnupgOptions = Encryption settings + DomainSelect = Choose a domain } @@ -242,6 +244,7 @@ Lang { GnupgKeySize = Length of the key (bytes) GnupgKeyExpires = Expiration time (years) Never = never + NoDomainsAvailable = No domains are available. } @@ -295,5 +298,7 @@ Lang { GnupgKeyImport = Import a key GnupgGenerateKey = Generate the key for this list GnupgOptions = Encryption settings + AvailableDomains = Available domains } } + diff --git a/template/domain_select.cs b/template/domain_select.cs new file mode 100644 index 0000000..dd52147 --- /dev/null +++ b/template/domain_select.cs @@ -0,0 +1,22 @@ +
+

+
+ +
+ + + + + 0 ?> + + +

+ + +
+ diff --git a/template/language_select.cs b/template/language_select.cs index fbda572..9223517 100644 --- a/template/language_select.cs +++ b/template/language_select.cs @@ -4,10 +4,11 @@
" enctype="application/x-www-form-urlencoded"> + var:Data.List.Name ?>" /> + + - - :