diff --git a/nixos/modules/services/mail/postfix.nix b/nixos/modules/services/mail/postfix.nix index 2b9175036be..ab6ad390600 100644 --- a/nixos/modules/services/mail/postfix.nix +++ b/nixos/modules/services/mail/postfix.nix @@ -9,14 +9,14 @@ let group = cfg.group; setgidGroup = cfg.setgidGroup; + haveAliases = cfg.postmasterAlias != "" || cfg.rootAlias != "" || cfg.extraAliases != ""; + haveTransport = cfg.transport != ""; + haveVirtual = cfg.virtual != ""; + mainCf = '' compatibility_level = 2 - queue_directory = /var/postfix/queue - command_directory = ${pkgs.postfix}/sbin - daemon_directory = ${pkgs.postfix}/libexec/postfix - mail_owner = ${user} default_privs = nobody @@ -57,8 +57,6 @@ let else "[" + cfg.relayHost + "]"} - alias_maps = hash:/var/postfix/conf/aliases - mail_spool_directory = /var/spool/mail/ setgid_group = ${setgidGroup} @@ -80,12 +78,15 @@ let + optionalString (cfg.recipientDelimiter != "") '' recipient_delimiter = ${cfg.recipientDelimiter} '' - + optionalString (cfg.virtual != "") '' - virtual_alias_maps = hash:/etc/postfix/virtual + + optionalString haveAliases '' + alias_maps = hash:/etc/postfix/aliases '' - + optionalString (cfg.transport != "") '' + + optionalString haveTransport '' transport_maps = hash:/etc/postfix/transport '' + + optionalString haveVirtual '' + virtual_alias_maps = hash:/etc/postfix/virtual + '' + cfg.extraConfig; masterCf = '' @@ -158,6 +159,7 @@ in services.postfix = { enable = mkOption { + type = types.bool; default = false; description = "Whether to run the Postfix mail server."; }; @@ -168,21 +170,25 @@ in }; setSendmail = mkOption { + type = types.bool; default = true; description = "Whether to set the system sendmail to postfix's."; }; user = mkOption { + type = types.str; default = "postfix"; description = "What to call the Postfix user (must be used only for postfix)."; }; group = mkOption { + type = types.str; default = "postfix"; description = "What to call the Postfix group (must be used only for postfix)."; }; setgidGroup = mkOption { + type = types.str; default = "postdrop"; description = " How to call postfix setgid group (for postdrop). Should @@ -191,6 +197,7 @@ in }; networks = mkOption { + type = types.nullOr (types.listOf types.str); default = null; example = ["192.168.0.1/24"]; description = " @@ -201,6 +208,7 @@ in }; networksStyle = mkOption { + type = types.str; default = ""; description = " Name of standard way of trusted network specification to use, @@ -210,6 +218,7 @@ in }; hostname = mkOption { + type = types.str; default = ""; description =" Hostname to use. Leave blank to use just the hostname of machine. @@ -218,6 +227,7 @@ in }; domain = mkOption { + type = types.str; default = ""; description =" Domain to use. Leave blank to use hostname minus first component. @@ -225,6 +235,7 @@ in }; origin = mkOption { + type = types.str; default = ""; description =" Origin to use in outgoing e-mail. Leave blank to use hostname. @@ -232,6 +243,7 @@ in }; destination = mkOption { + type = types.nullOr (types.listOf types.str); default = null; example = ["localhost"]; description = " @@ -241,6 +253,7 @@ in }; relayDomains = mkOption { + type = types.nullOr (types.listOf types.str); default = null; example = ["localdomain"]; description = " @@ -249,6 +262,7 @@ in }; relayHost = mkOption { + type = types.str; default = ""; description = " Mail relay for outbound mail. @@ -256,6 +270,7 @@ in }; lookupMX = mkOption { + type = types.bool; default = false; description = " Whether relay specified is just domain whose MX must be used. @@ -263,11 +278,13 @@ in }; postmasterAlias = mkOption { + type = types.str; default = "root"; description = "Who should receive postmaster e-mail."; }; rootAlias = mkOption { + type = types.str; default = ""; description = " Who should receive root e-mail. Blank for no redirection. @@ -275,6 +292,7 @@ in }; extraAliases = mkOption { + type = types.lines; default = ""; description = " Additional entries to put verbatim into aliases file, cf. man-page aliases(8). @@ -282,6 +300,7 @@ in }; extraConfig = mkOption { + type = types.str; default = ""; description = " Extra lines to be added verbatim to the main.cf configuration file. @@ -289,21 +308,25 @@ in }; sslCert = mkOption { + type = types.str; default = ""; description = "SSL certificate to use."; }; sslCACert = mkOption { + type = types.str; default = ""; description = "SSL certificate of CA."; }; sslKey = mkOption { + type = types.str; default = ""; description = "SSL key to use."; }; recipientDelimiter = mkOption { + type = types.str; default = ""; example = "+"; description = " @@ -312,6 +335,7 @@ in }; virtual = mkOption { + type = types.lines; default = ""; description = " Entries for the virtual alias map, cf. man-page virtual(8). @@ -326,11 +350,24 @@ in }; extraMasterConf = mkOption { + type = types.lines; default = ""; example = "submission inet n - n - - smtpd"; description = "Extra lines to append to the generated master.cf file."; }; + aliasFiles = mkOption { + type = types.attrsOf types.path; + default = {}; + description = "Aliases' tables to be compiled and placed into /var/lib/postfix/conf."; + }; + + mapFiles = mkOption { + type = types.attrsOf types.path; + default = {}; + description = "Maps to be compiled and placed into /var/lib/postfix/conf."; + }; + }; }; @@ -338,91 +375,104 @@ in ###### implementation - config = mkIf config.services.postfix.enable { + config = mkIf config.services.postfix.enable (mkMerge [ + { - environment = { - etc = singleton - { source = "/var/postfix/conf"; - target = "postfix"; - }; + environment = { + etc = singleton + { source = "/var/lib/postfix/conf"; + target = "postfix"; + }; - # This makes comfortable for root to run 'postqueue' for example. - systemPackages = [ pkgs.postfix ]; - }; - - services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail { - program = "sendmail"; - source = "${pkgs.postfix}/bin/sendmail"; - owner = "nobody"; - group = "postdrop"; - setuid = false; - setgid = true; - }; - - users.extraUsers = singleton - { name = user; - description = "Postfix mail server user"; - uid = config.ids.uids.postfix; - group = group; + # This makes comfortable for root to run 'postqueue' for example. + systemPackages = [ pkgs.postfix ]; }; - users.extraGroups = - [ { name = group; + services.mail.sendmailSetuidWrapper = mkIf config.services.postfix.setSendmail { + program = "sendmail"; + source = "${pkgs.postfix}/bin/sendmail"; + group = setgidGroup; + setuid = false; + setgid = true; + }; + + users.extraUsers = optional (user == "postfix") + { name = "postfix"; + description = "Postfix mail server user"; + uid = config.ids.uids.postfix; + group = group; + }; + + users.extraGroups = + optional (group == "postfix") + { name = group; gid = config.ids.gids.postfix; } + ++ optional (setgidGroup == "postdrop") { name = setgidGroup; gid = config.ids.gids.postdrop; - } - ]; - - systemd.services.postfix = - { description = "Postfix mail server"; - - wantedBy = [ "multi-user.target" ]; - after = [ "network.target" ]; - - serviceConfig = { - Type = "forking"; - Restart = "always"; - PIDFile = "/var/postfix/queue/pid/master.pid"; }; - preStart = '' - ${pkgs.coreutils}/bin/mkdir -p /var/spool/mail /var/postfix/conf /var/postfix/queue + systemd.services.postfix = + { description = "Postfix mail server"; - ${pkgs.coreutils}/bin/chown -R ${user}:${group} /var/postfix - ${pkgs.coreutils}/bin/chown -R ${user}:${setgidGroup} /var/postfix/queue - ${pkgs.coreutils}/bin/chmod -R ug+rwX /var/postfix/queue - ${pkgs.coreutils}/bin/chown root:root /var/spool/mail - ${pkgs.coreutils}/bin/chmod a+rwxt /var/spool/mail - ${pkgs.coreutils}/bin/ln -sf /var/spool/mail /var/ + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + path = [ pkgs.postfix ]; - ln -sf ${pkgs.postfix}/etc/postfix/postfix-files /var/postfix/conf + serviceConfig = { + Type = "forking"; + Restart = "always"; + PIDFile = "/var/lib/postfix/queue/pid/master.pid"; + ExecStart = "${pkgs.postfix}/bin/postfix start"; + ExecStop = "${pkgs.postfix}/bin/postfix stop"; + ExecReload = "${pkgs.postfix}/bin/postfix reload"; + }; - ln -sf ${aliasesFile} /var/postfix/conf/aliases - ln -sf ${virtualFile} /var/postfix/conf/virtual - ln -sf ${mainCfFile} /var/postfix/conf/main.cf - ln -sf ${masterCfFile} /var/postfix/conf/master.cf - ln -sf ${transportFile} /var/postfix/conf/transport + preStart = '' + # Backwards compatibility + if [ ! -d /var/lib/postfix ] && [ -d /var/postfix ]; then + mkdir -p /var/lib + mv /var/postfix /var/lib/postfix + fi + mkdir -p /var/lib/postfix/data /var/lib/postfix/queue/{pid,public,maildrop} - ${pkgs.postfix}/sbin/postalias -c /var/postfix/conf /var/postfix/conf/aliases - ${pkgs.postfix}/sbin/postmap -c /var/postfix/conf /var/postfix/conf/virtual - ''; + chown -R ${user}:${group} /var/lib/postfix + chown root /var/lib/postfix/queue + chown root /var/lib/postfix/queue/pid + chgrp -R ${setgidGroup} /var/lib/postfix/queue/{public,maildrop} + chmod 770 /var/lib/postfix/queue/{public,maildrop} - script = '' - ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf start - ''; + rm -rf /var/lib/postfix/conf + mkdir -p /var/lib/postfix/conf + ln -sf ${mainCfFile} /var/lib/postfix/conf/main.cf + ln -sf ${masterCfFile} /var/lib/postfix/conf/master.cf + ${concatStringsSep "\n" (mapAttrsToList (to: from: '' + ln -sf ${from} /var/lib/postfix/conf/${to} + postalias /var/lib/postfix/conf/${to} + '') cfg.aliasFiles)} + ${concatStringsSep "\n" (mapAttrsToList (to: from: '' + ln -sf ${from} /var/lib/postfix/conf/${to} + postmap /var/lib/postfix/conf/${to} + '') cfg.mapFiles)} - reload = '' - ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf reload - ''; + mkdir -p /var/spool/mail + chown root:root /var/spool/mail + chmod a+rwxt /var/spool/mail + ln -sf /var/spool/mail /var/ + ''; + }; + } - preStop = '' - ${pkgs.postfix}/sbin/postfix -c /var/postfix/conf stop - ''; - - }; - - }; + (mkIf haveAliases { + services.postfix.aliasFiles."aliases" = aliasesFile; + }) + (mkIf haveTransport { + services.postfix.mapFiles."transport" = transportFile; + }) + (mkIf haveVirtual { + services.postfix.mapFiles."virtual" = virtualFile; + }) + ]); } diff --git a/pkgs/servers/mail/postfix/3.0.nix b/pkgs/servers/mail/postfix/3.0.nix index 8c625da2c9e..73ab8c8116f 100644 --- a/pkgs/servers/mail/postfix/3.0.nix +++ b/pkgs/servers/mail/postfix/3.0.nix @@ -1,8 +1,25 @@ -{ stdenv, fetchurl, makeWrapper, gnused, db, openssl, cyrus_sasl, coreutils -, findutils, gnugrep, gawk, icu +{ stdenv, lib, fetchurl, makeWrapper, gnused, db, openssl, cyrus_sasl +, coreutils, findutils, gnugrep, gawk, icu, pcre +, withPgSQL ? false, postgresql +, withMySQL ? false, libmysql +, withSQLite ? false, sqlite }: -stdenv.mkDerivation rec { +let + ccargs = lib.concatStringsSep " " ([ + "-DUSE_TLS" "-DUSE_SASL_AUTH" "-DUSE_CYRUS_SASL" "-I${cyrus_sasl}/include/sasl" + "-DHAS_DB_BYPASS_MAKEDEFS_CHECK" + "-fPIE" "-fstack-protector-all" "--param" "ssp-buffer-size=4" "-O2" "-D_FORTIFY_SOURCE=2" + ] ++ lib.optional withPgSQL "-DHAS_PGSQL" + ++ lib.optionals withMySQL [ "-DHAS_MYSQL" "-I${libmysql}/include/mysql" ] + ++ lib.optional withSQLite "-DHAS_SQLITE"); + auxlibs = lib.concatStringsSep " " ([ + "-ldb" "-lnsl" "-lresolv" "-lsasl2" "-lcrypto" "-lssl" "-pie" "-Wl,-z,relro,-z,now" + ] ++ lib.optional withPgSQL "-lpq" + ++ lib.optional withMySQL "-lmysqlclient" + ++ lib.optional withSQLite "-lsqlite3"); + +in stdenv.mkDerivation rec { name = "postfix-${version}"; @@ -13,35 +30,35 @@ stdenv.mkDerivation rec { sha256 = "00mc12k5p1zlrlqcf33vh5zizaqr5ai8q78dwv69smjh6kn4c7j0"; }; - buildInputs = [ makeWrapper gnused db openssl cyrus_sasl icu ]; + buildInputs = [ makeWrapper gnused db openssl cyrus_sasl icu pcre ] + ++ lib.optional withPgSQL postgresql + ++ lib.optional withMySQL libmysql + ++ lib.optional withSQLite sqlite; - patches = [ ./postfix-script-shell.patch ]; + patches = [ ./postfix-script-shell.patch ./postfix-3.0-no-warnings.patch ]; preBuild = '' sed -e '/^PATH=/d' -i postfix-install export command_directory=$out/sbin export config_directory=/etc/postfix + export meta_directory=$out/etc/postfix export daemon_directory=$out/libexec/postfix - export data_directory=/var/lib/postfix + export data_directory=/var/lib/postfix/data export html_directory=$out/share/postfix/doc/html export mailq_path=$out/bin/mailq export manpage_directory=$out/share/man export newaliases_path=$out/bin/newaliases - export queue_directory=/var/spool/postfix + export queue_directory=/var/lib/postfix/queue export readme_directory=$out/share/postfix/doc export sendmail_path=$out/bin/sendmail - make makefiles \ - CCARGS='-DUSE_TLS -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I${cyrus_sasl}/include/sasl \ - -DHAS_DB_BYPASS_MAKEDEFS_CHECK \ - -fPIE -fstack-protector-all --param ssp-buffer-size=4 -O2 -D_FORTIFY_SOURCE=2' \ - AUXLIBS='-ldb -lnsl -lresolv -lsasl2 -lcrypto -lssl -pie -Wl,-z,relro,-z,now' + make makefiles CCARGS='${ccargs}' AUXLIBS='${auxlibs}' ''; installTargets = [ "non-interactive-package" ]; - installFlags = [ " install_root=installdir " ]; + installFlags = [ "install_root=installdir" ]; postInstall = '' mkdir -p $out @@ -57,9 +74,9 @@ stdenv.mkDerivation rec { meta = { homepage = "http://www.postfix.org/"; description = "A fast, easy to administer, and secure mail server"; - license = stdenv.lib.licenses.bsdOriginal; - platforms = stdenv.lib.platforms.linux; - maintainers = [ stdenv.lib.maintainers.rickynils ]; + license = lib.licenses.bsdOriginal; + platforms = lib.platforms.linux; + maintainers = [ lib.maintainers.rickynils ]; }; } diff --git a/pkgs/servers/mail/postfix/postfix-3.0-no-warnings.patch b/pkgs/servers/mail/postfix/postfix-3.0-no-warnings.patch new file mode 100644 index 00000000000..d93eaf0aaa0 --- /dev/null +++ b/pkgs/servers/mail/postfix/postfix-3.0-no-warnings.patch @@ -0,0 +1,86 @@ +diff -ru3 postfix-3.0.3/conf/postfix-script postfix-3.0.3-new/conf/postfix-script +--- postfix-3.0.3/conf/postfix-script 2014-06-27 18:05:15.000000000 +0400 ++++ postfix-3.0.3-new/conf/postfix-script 2016-01-09 17:51:38.545733631 +0300 +@@ -84,24 +84,6 @@ + exit 1 + } + +-# If this is a secondary instance, don't touch shared files. +- +-instances=`test ! -f $def_config_directory/main.cf || +- $command_directory/postconf -c $def_config_directory \ +- -h multi_instance_directories | sed 's/,/ /'` || { +- $FATAL cannot execute $command_directory/postconf! +- exit 1 +-} +- +-check_shared_files=1 +-for name in $instances +-do +- case "$name" in +- "$def_config_directory") ;; +- "$config_directory") check_shared_files=; break;; +- esac +-done +- + # + # Parse JCL + # +@@ -262,22 +244,6 @@ + -prune \( -perm -020 -o -perm -002 \) \ + -exec $WARN group or other writable: {} \; + +- # Check Postfix root-owned directory tree owner/permissions. +- +- todo="$config_directory/." +- test -n "$check_shared_files" && { +- todo="$daemon_directory/. $meta_directory/. $todo" +- test "$shlib_directory" = "no" || +- todo="$shlib_directory/. $todo" +- } +- todo=`echo "$todo" | tr ' ' '\12' | sort -u` +- +- find $todo ! -user root \ +- -exec $WARN not owned by root: {} \; +- +- find $todo \( -perm -020 -o -perm -002 \) \ +- -exec $WARN group or other writable: {} \; +- + # Check Postfix mail_owner-owned directory tree owner/permissions. + + find $data_directory/. ! -user $mail_owner \ +@@ -302,18 +268,11 @@ + # Check Postfix setgid_group-owned directory and file group/permissions. + + todo="$queue_directory/public $queue_directory/maildrop" +- test -n "$check_shared_files" && +- todo="$command_directory/postqueue $command_directory/postdrop $todo" + + find $todo \ + -prune ! -group $setgid_group \ + -exec $WARN not owned by group $setgid_group: {} \; + +- test -n "$check_shared_files" && +- find $command_directory/postqueue $command_directory/postdrop \ +- -prune ! -perm -02111 \ +- -exec $WARN not set-gid or not owner+group+world executable: {} \; +- + # Check non-Postfix root-owned directory tree owner/content. + + for dir in bin etc lib sbin usr +@@ -334,15 +293,6 @@ + + find corrupt -type f -exec $WARN damaged message: {} \; + +- # Check for non-Postfix MTA remnants. +- +- test -n "$check_shared_files" -a -f /usr/sbin/sendmail -a \ +- -f /usr/lib/sendmail && { +- cmp -s /usr/sbin/sendmail /usr/lib/sendmail || { +- $WARN /usr/lib/sendmail and /usr/sbin/sendmail differ +- $WARN Replace one by a symbolic link to the other +- } +- } + exit 0 + ;; +