diff --git a/.gitattributes b/.gitattributes index ec160f2f..b3e9ab17 100644 --- a/.gitattributes +++ b/.gitattributes @@ -421,9 +421,11 @@ etc/alternc/templates/dovecot/dovecot-dict-quota.conf -text etc/alternc/templates/dovecot/dovecot-sql.conf -text etc/alternc/templates/dovecot/dovecot.conf -text etc/alternc/templates/postfix/ca.der -text +etc/alternc/templates/postfix/master.cf -text etc/alternc/templates/postfix/myalias.cf -text etc/alternc/templates/postfix/mydomain.cf -text etc/alternc/templates/postfix/mygid.cf -text +etc/alternc/templates/postfix/myquota.cf -text etc/alternc/templates/postfix/myrelay.cf -text etc/alternc/templates/postfix/myvirtual.cf -text etc/alternc/templates/postfix/sasl/smtpd.conf -text @@ -515,6 +517,7 @@ tests/whois_test.php -text tools/alternc_get_path -text tools/get_account_by_domain -text tools/get_domains_by_account -text +tools/postfix-add-policy -text tools/top_ftp_users -text tools/top_http_users -text tools/top_mysql_users -text diff --git a/debian/alternc.config b/debian/alternc.config index 848e3baf..0053a911 100644 --- a/debian/alternc.config +++ b/debian/alternc.config @@ -1,7 +1,6 @@ #! /bin/sh set -e - # Source debconf library. . /usr/share/debconf/confmodule db_title AlternC @@ -26,7 +25,7 @@ MYSQL_HOST=127.0.0.1 MYSQL_DATABASE=alternc MYSQL_USER=sysusr MYSQL_PASS="`perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..10)' `" -MYSQL_MAIL_USER=alternc_mail_user +MYSQL_MAIL_USER=alternc_user MYSQL_MAIL_PASS="`perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..10)' `" MYSQL_CLIENT=localhost FQDN="`cat /etc/mailname 2>/dev/null || hostname -f`" @@ -169,11 +168,13 @@ if [ -z "$RET" ] db_set alternc/alternc_location "$ALTERNC_LOC" fi +db_get alternc/mysql/alternc_mail_user if [ -z "$RET" ] then db_set alternc/mysql/alternc_mail_user "$MYSQL_MAIL_USER" fi +db_get alternc/mysql/alternc_mail_password if [ -z "$RET" ] then db_set alternc/mysql/alternc_mail_password "$MYSQL_MAIL_PASS" diff --git a/debian/alternc.postinst b/debian/alternc.postinst index 88efdd98..a906c185 100644 --- a/debian/alternc.postinst +++ b/debian/alternc.postinst @@ -46,6 +46,18 @@ case "$1" in mkdir -p /var/spool/postfix/var/run/saslauthd || true dpkg-statoverride --quiet --update --add root sasl 710 /var/spool/postfix/var/run/saslauthd || true + + #Create Dovecot user for mail handling FIXME change home with ALTERNC_LOC + if ! getent group vmail; then + addgroup --gid 1998 vmail + fi + if ! getent passwd vmail; then + adduser -g vmail -u 1998 vmail -d /var/alternc/mail -m + fi + chown -R vmail:vmail /var/alternc/mail + chmod u+w /var/alternc/mail + + # build local.sh if it does not exist if [ ! -f $CONFIGFILE ]; then cat > $CONFIGFILE < # -mail_location = maildir:~/Maildir +mail_location = maildir:~/Maildir # If you need to set multiple mailbox locations or want to change default # namespace settings, you can do it by defining namespace sections. @@ -699,7 +699,7 @@ protocol pop3 { # Support for dynamically loadable plugins. mail_plugins is a space separated # list of plugins to load. #mail_plugins = - mail_plugins = quota + mail_plugins = quota #mail_plugin_dir = /usr/lib/dovecot/modules/pop3 # Workarounds for various client bugs: @@ -755,7 +755,7 @@ protocol managesieve { protocol lda { # Address to use when sending rejection mails (e.g. postmaster@example.com). - postmaster_address = postmaster@lautre.net + postmaster_address = postmaster@localhost # Hostname to use in various parts of sent mails, eg. in Message-Id. # Default is the system's real hostname. @@ -1127,9 +1127,9 @@ auth default { # used to give Dovecot's local delivery agent access to userdb so it # can find mailbox locations. path = /var/run/dovecot/auth-master - mode = 0666 + mode = 0600 # Default user/group is the one who started dovecot-auth (root) - user = vmail + user = vmail #group = } client { @@ -1168,7 +1168,7 @@ auth default { # format "proxy::". dict { - quota = mysql:/etc/dovecot/dovecot-dict-quota.conf + quotadict = mysql:/etc/dovecot/dovecot-dict-quota.conf #expire = db:/var/lib/dovecot/expire.db } @@ -1216,7 +1216,7 @@ plugin { # quota_warning2 = storage=80%% /usr/local/bin/quota-warning.sh 80 quota_warning = storage=80%% /usr/local/bin/quota-warning.sh 80 #quota = maildir - quota = dict:user:proxy::quotadict + quota = dict:user::proxy::quotadict # ACL plugin. vfile backend reads ACLs from "dovecot-acl" file from maildir # directory. You can also optionally give a global ACL directory path where diff --git a/etc/alternc/templates/postfix/master.cf b/etc/alternc/templates/postfix/master.cf new file mode 100644 index 00000000..cec4bb84 --- /dev/null +++ b/etc/alternc/templates/postfix/master.cf @@ -0,0 +1,113 @@ +# +# Postfix master process configuration file. For details on the format +# of the file, see the master(5) manual page (command: "man 5 master"). +# +# Do not forget to execute "postfix reload" after editing this file. +# +# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +smtp inet n - - - - smtpd +#submission inet n - - - - smtpd +# -o smtpd_tls_security_level=encrypt +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_client_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +#smtps inet n - - - - smtpd +# -o smtpd_tls_wrappermode=yes +# -o smtpd_sasl_auth_enable=yes +# -o smtpd_client_restrictions=permit_sasl_authenticated,reject +# -o milter_macro_daemon_name=ORIGINATING +#628 inet n - - - - qmqpd +pickup fifo n - - 60 1 pickup +cleanup unix n - - - 0 cleanup +qmgr fifo n - n 300 1 qmgr +#qmgr fifo n - - 300 1 oqmgr +tlsmgr unix - - - 1000? 1 tlsmgr +rewrite unix - - - - - trivial-rewrite +bounce unix - - - - 0 bounce +defer unix - - - - 0 bounce +trace unix - - - - 0 bounce +verify unix - - - - 1 verify +flush unix n - - 1000? 0 flush +proxymap unix - - n - - proxymap +proxywrite unix - - n - 1 proxymap +smtp unix - - - - - smtp +# When relaying mail as backup MX, disable fallback_relay to avoid MX loops +relay unix - - - - - smtp + -o smtp_fallback_relay= +# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 +showq unix n - - - - showq +error unix - - - - - error +retry unix - - - - - error +discard unix - - - - - discard +local unix - n n - - local +virtual unix - n n - - virtual +lmtp unix - - - - - lmtp +anvil unix - - - - 1 anvil +scache unix - - - - 1 scache +# +# ==================================================================== +# Interfaces to non-Postfix software. Be sure to examine the manual +# pages of the non-Postfix software to find out what options it wants. +# +# Many of the following services use the Postfix pipe(8) delivery +# agent. See the pipe(8) man page for information about ${recipient} +# and other message envelope options. +# ==================================================================== +# +# maildrop. See the Postfix MAILDROP_README file for details. +# Also specify in main.cf: maildrop_destination_recipient_limit=1 +# +maildrop unix - n n - - pipe + flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient} +# +# ==================================================================== +# +# Recent Cyrus versions can use the existing "lmtp" master.cf entry. +# +# Specify in cyrus.conf: +# lmtp cmd="lmtpd -a" listen="localhost:lmtp" proto=tcp4 +# +# Specify in main.cf one or more of the following: +# mailbox_transport = lmtp:inet:localhost +# virtual_transport = lmtp:inet:localhost +# +# ==================================================================== +# +# Cyrus 2.1.5 (Amos Gouaux) +# Also specify in main.cf: cyrus_destination_recipient_limit=1 +# +#cyrus unix - n n - - pipe +# user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} +# +# ==================================================================== +# Old example of delivery via Cyrus. +# +#old-cyrus unix - n n - - pipe +# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} +# +# ==================================================================== +# +# See the Postfix UUCP_README file for configuration details. +# +uucp unix - n n - - pipe + flags=Fqhu user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) +# +# Other external delivery methods. +# +ifmail unix - n n - - pipe + flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) +bsmtp unix - n n - - pipe + flags=Fq. user=bsmtp argv=/usr/lib/bsmtp/bsmtp -t$nexthop -f$sender $recipient +scalemail-backend unix - n n - 2 pipe + flags=R user=scalemail argv=/usr/lib/scalemail/bin/scalemail-store ${nexthop} ${user} ${extension} +mailman unix - n n - - pipe + flags=FR user=list argv=/usr/lib/mailman/bin/postfix-to-mailman.py + ${nexthop} ${user} +#dovecot LDA, as explained here: http://wiki.dovecot.org/LDA/Postfix +dovecot unix - n n - - pipe flags=DRhu user=vmail argv=/usr/lib/dovecot/deliver -f ${sender} -d ${recipient} + + + diff --git a/etc/alternc/templates/postfix/myalias.cf b/etc/alternc/templates/postfix/myalias.cf index 9ffc2873..cc62b80b 100644 --- a/etc/alternc/templates/postfix/myalias.cf +++ b/etc/alternc/templates/postfix/myalias.cf @@ -6,8 +6,6 @@ user = %%db_mail_user%% password = %%db_mail_pwd%% hosts =%%dbhost%% dbname = %%dbname%% -query = select concat( if(isnull(mailbox.id), '', concat(concat(address.address,'@',domaines.domaine), '\n')), recipient.recipients ) from recipient join address on address.id = re -cipient.address_id left outer join mailbox on mailbox.address_id = address.id join domaines on domaines.id = address.domain_id where concat(address.address,'@',domaines.domaine)='% -s'; +query = select concat( if(isnull(mailbox.id), '', concat(concat(address.address,'@',domaines.domaine), '\n')), recipient.recipients ) from recipient join address on address.id = recipient.address_id left outer join mailbox on mailbox.address_id = address.id join domaines on domaines.id = address.domain_id where concat(address.address,'@',domaines.domaine)='%s'; diff --git a/etc/alternc/templates/postfix/mydomain.cf b/etc/alternc/templates/postfix/mydomain.cf index 8c7fd32f..c1c8da40 100644 --- a/etc/alternc/templates/postfix/mydomain.cf +++ b/etc/alternc/templates/postfix/mydomain.cf @@ -6,5 +6,5 @@ user = %%db_mail_user%% password = %%db_mail_pwd%% hosts =%%dbhost%% dbname = %%dbname%% -query = select domaines.domaine from domaines where domaine='%s' and gesmx=1; +query = select domaines.domaine from domaines join address on address.id=domaines.id where concat(address.address,'@',domaines.domaine)='%s' and gesmx=1; diff --git a/etc/alternc/templates/postfix/mygid.cf b/etc/alternc/templates/postfix/mygid.cf index c8193fc0..76adeca3 100644 --- a/etc/alternc/templates/postfix/mygid.cf +++ b/etc/alternc/templates/postfix/mygid.cf @@ -6,5 +6,5 @@ user = %%db_mail_user%% password = %%db_mail_pwd%% hosts =%%dbhost%% dbname = %%dbname%% -query = select compte from domaines join address on address.domain_id = domaines.id join mailbox on mailbox.address_id = address.id where address.address='%s' +query = select compte from domaines join address on address.domain_id = domaines.id join mailbox on mailbox.address_id = address.id where concat(address.address,'@',domaines.domaine)='%s' diff --git a/etc/alternc/templates/postfix/myquota.cf b/etc/alternc/templates/postfix/myquota.cf new file mode 100644 index 00000000..a21c7271 --- /dev/null +++ b/etc/alternc/templates/postfix/myquota.cf @@ -0,0 +1,11 @@ +# +# WARNING: Do not edit this file, edit the one in /etc/alternc/templates and launch alternc.install again. +# Get the quota +# + +user = sysusr +password = bGwD2GlLOX +hosts =127.0.0.1 +dbname = alternc +query = select quota from mailbox join address on mailbox.id = address.id join domaines on domaines.id = address.id where concat(address.address,'@',domaines.domaine) = '%s' + diff --git a/etc/alternc/templates/postfix/myvirtual.cf b/etc/alternc/templates/postfix/myvirtual.cf index 7b28e63f..31dbb060 100644 --- a/etc/alternc/templates/postfix/myvirtual.cf +++ b/etc/alternc/templates/postfix/myvirtual.cf @@ -6,6 +6,5 @@ user = %%db_mail_user%% password = %%db_mail_pwd%% hosts =%%dbhost%% dbname = %%dbname%% -query = select concat(path, '/Maildir/') from mailbox join address on address.id = mailbox.address_id join domaines on domaines.id = address.domain_id where concat(address.address, -'@',domaines.domaine) ='%s'; +query = select concat(path, '/Maildir/') from mailbox join address on address.id = mailbox.address_id join domaines on domaines.id = address.domain_id where concat(address.address,'@',domaines.domaine) ='%s'; diff --git a/install/alternc.install b/install/alternc.install index 3f236164..42d89f3d 100644 --- a/install/alternc.install +++ b/install/alternc.install @@ -118,7 +118,7 @@ if [ -r /etc/alternc/my_mail.cnf ]; then # * add a right quote operator at the end of line (;s) # * convert mysql variables into our MYSQL_ naming convention (;s) # * print the result (;p) - eval `sed -n -e "/=/{s/ *= *\"\?/='/;s/\"\?\$/'/;s/host/MYSQL_HOST/;s/user/MYSQL_USER/;s/password/MYSQL_PASS/;s/database/MYSQL_DATABASE/;p}" /etc/alternc/my.cnf` + eval `sed -n -e "/=/{s/ *= *\"\?/='/;s/\"\?\$/'/;s/host/MYSQL_HOST/;s/user/MYSQL_MAIL_USER/;s/password/MYSQL_MAIL_PASS/;s/database/MYSQL_DATABASE/;p}" /etc/alternc/my_mail.cnf` chown root:alterncpanel /etc/alternc/my_mail.cnf chmod 640 /etc/alternc/my_mail.cnf fi @@ -280,16 +280,18 @@ then exit 1 fi -# configure postfix appropriatly for our needs +# configure Postfix appropriatly for our needs if [ "$slave" = "1" ]; then postfix_conf=/etc/alternc/postfix-slave.cf else postfix_conf=/etc/alternc/postfix.cf fi -while read line -do +while read line ; do postconf -e "$line" -done < $postfix_conf +done < "$postfix_conf" + +# Conviguring delivery used bu Postfix FIXME change script name +echo `/usr/bin/postfix-add-policy2 dovecot pipe DRhu vmail:vmail '/usr/lib/dovecot/deliver -f ${sender} -d ${recipient} '` # Bug #1215: configure mydestination when $FQDN is not in OLDDESTINATION=`postconf mydestination | awk -F '=' '{print $2}'` @@ -366,6 +368,10 @@ if [ "$HAS_ROOT" != "1" ]; then fi fi +#giving vmail user read access on dovecot sql file +chgrp vmail /etc/dovecot/dovecot.conf +chmod g+r /etc/dovecot/dovecot.conf + # Changing owner of web panel's files chown -R alterncpanel:alterncpanel "$ALTERNC_LOC/bureau" diff --git a/install/mysql.sh b/install/mysql.sh index fea689a5..f2d8c277 100755 --- a/install/mysql.sh +++ b/install/mysql.sh @@ -34,8 +34,8 @@ # * user # * password # * database -# * mail_user -# * mail_password +# * alternc_mail_user +# * alternc_mail_password # * MYSQL_CLIENT # # XXX: the sed script should be generated here @@ -55,7 +55,9 @@ MYSQL_MAIL_CONFIG="/etc/alternc/my_mail.cnf" # the purpose of this "grant" is to make sure that the generated my.cnf works # this means (a) creating the user and (b) creating the database grant="GRANT ALL ON *.* TO '$user'@'${MYSQL_CLIENT}' IDENTIFIED BY '$password' WITH GRANT OPTION; -CREATE DATABASE IF NOT EXISTS $database;GRANT ALL ON '$database'.dovecot_view TO '$mail_user'@'${MYSQL_CLIENT}' IDENTIFIED BY '$mail_password'; " +CREATE DATABASE IF NOT EXISTS $database; " +grant_mail="GRANT ALL ON $database.dovecot_view TO '$alternc_mail_user'@'${MYSQL_CLIENT}' IDENTIFIED BY '$alternc_mail_password';" +grant_mail=$grant_mail"GRANT SELECT ON $database.* TO '$alternc_mail_user'@'${MYSQL_CLIENT}' IDENTIFIED BY '$alternc_mail_password';" echo -n "Trying debian.cnf: " mysql="/usr/bin/mysql --defaults-file=/etc/mysql/debian.cnf" @@ -136,10 +138,15 @@ set_value() { RET=$2 file=$3 grep -Eq "^ *$var=" $file || echo "$var=" >> $file - SED_SCRIPT="$SED_SCRIPT;s\\^ *$var=.*\\$var=\"$RET\"\\" + if [ $file = $MYSQL_CONFIG ]; then + SED_SCRIPT_USR="$SED_SCRIPT_USR;s\\^ *$var=.*\\$var=\"$RET\"\\" + else + SED_SCRIPT_MAIL="$SED_SCRIPT_MAIL;s\\^ *$var=.*\\$var=\"$RET\"\\" + fi } -SED_SCRIPT="" +SED_SCRIPT_USR="" +SED_SCRIPT_MAIL="" # hostname was empty in older (pre-0.9.6?) versions if [ -z "$host" ]; then host="localhost" @@ -154,29 +161,41 @@ set_value password $password $MYSQL_CONFIG #filling the config file for the mailuser set_value host $host $MYSQL_MAIL_CONFIG set_value database $database $MYSQL_MAIL_CONFIG -set_value user $mail_user $MYSQL_MAIL_CONFIG -set_value password $mail_password $MYSQL_MAIL_CONFIG +set_value user $alternc_mail_user $MYSQL_MAIL_CONFIG +set_value password $alternc_mail_password $MYSQL_MAIL_CONFIG +echo $SED_SCRIPT_MAIL +echo XXXXXX +echo $SED_SCRIPT_USR # take extra precautions here with the mysql password: # put the sed script in a temporary file SED_SCRIPT_NAME=`mktemp` cat > $SED_SCRIPT_NAME < $MYSQL_CONFIG.$$ mv -f $MYSQL_CONFIG.$$ $MYSQL_CONFIG rm -f $SED_SCRIPT_NAME +SED_SCRIPT_NAME_MAIL=`mktemp` +cat > $SED_SCRIPT_NAME_MAIL < $MYSQL_MAIL_CONFIG.$$ +mv -f $MYSQL_MAIL_CONFIG.$$ $MYSQL_MAIL_CONFIG +rm -f $SED_SCRIPT_NAME_MAIL + # Now we should be able to use the mysql configuration mysql="/usr/bin/mysql --defaults-file=$MYSQL_CONFIG" mysql_mail="/usr/bin/mysql --defaults-file=$MYSQL_MAIL_CONFIG" echo "Checking for MySQL connectivity" $mysql -e "SHOW TABLES" >/dev/null && echo "MYSQL.SH OK!" || echo "MYSQL.SH FAILED: database user setup failed" -$mysql_mail -e "SHOW TABLES" >/dev/null && echo "MYSQL.SH OK!" || echo "MYSQL.SH FAILED: database mail user setup failed" - +echo $grant_mail # Final mysql setup: db schema echo "installing AlternC schema in $database..." $mysql < /usr/share/alternc/install/mysql.sql || echo cannot load database schema - +$mysql < +Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +''' +__author__ = "Scott Kitterman" +__email__ = "scott@kitterman.com" +__version__ = "0.1: August 3, 2008" + +import sys +import shutil +import os +import time +import fileinput + +def makepolicy(name, method, flags, user, argv): + # Recommendations from the Postfix SMTPD_POLICY_README. + header = """# ========================================================================== +# service type private unpriv chroot wakeup maxproc command + args +# (yes) (yes) (yes) (never) (100) +# ========================================================================== +# Added using postfix-add-policy script: +""" + policy = ("""%s unix - n n - 0 %s + %s user=%s argv=%s +""" % (name, method, flags, user, argv)) + additions = header + policy + return (additions) + + +USAGE = """To add a new policy service to your master.cf: + % sudo postfix-policy-add {policy service name} {user} {file (full path)} + +Example: + % sudo postfix-policy-add policyd noboby /usr/bin/policyd + +Adds the following to master.cf: +""" + makepolicy('policyd','method','flags', 'nobody', '/usr/bin/policyd') + """ +To output this usage message: + % postfix-add-policy +""" + + +if __name__ == '__main__': + import sys + if len(sys.argv) < 6: + print USAGE + elif len(sys.argv) == 6: + policyname = sys.argv[1] + user = sys.argv[2] + flags = sys.argv[3] + method = sys.argv[4] + argv = sys.argv[5] + # Read in master.cf and check to make sure specified name isn't + # already used + masterfile = open('/etc/postfix/master.cf', mode='r') + master = masterfile.readlines() + masterfile.close() + bailout = False + for line in master: + if policyname in line: + # Policy name already used, print error and bail + print ('Selected policy name, %s, already in master.cf. \ + Master.cf not updated.' % (policyname)) + bailout = True + break + if not bailout: + # Make backup copy + backupname = '/etc/postfix/master.cf.' + str(int(time.time())) + shutil.copy2('/etc/postfix/master.cf', backupname) + # Make working copy + shutil.copy2('/etc/postfix/master.cf', \ + '/etc/postfix/master.cf.working') + # Add stuff in + stuff = makepolicy(policyname, user, method, flags, argv) + # Append stuff to the working copy: + + newmaster = open('/etc/postfix/master.cf.working', mode='a') + newmaster.writelines(stuff) + + newmaster.close() + # Put working copy in place. + shutil.move('/etc/postfix/master.cf.working', \ + '/etc/postfix/master.cf') + else: + print USAGE +