ACC SHELL
/**
* File:
* modules/Mail.ycp
*
* Package:
* Configuration of mail
*
* Summary:
* Data for configuration of mail, input and output functions.
*
* Authors:
* Martin Vidner <mvidner@suse.cz>
*
* $Id: Mail.ycp 61601 2010-04-07 12:52:02Z varkoly $
*
* Representation of the configuration of mail.
* Input and output routines.
*
*/
{
// Set the name of the module
module "Mail";
textdomain "mail";
import "MailAliases";
import "MailTable";
import "Mode";
import "Report";
import "Service";
import "Summary";
import "Progress";
import "Package";
import "PackageSystem";
import "SuSEFirewall";
/* ---------------------------------------------------------------- */
/**
* Required packages
*/
global list required_packages = [];
/**
* `sendmail, `postfix or `other
* Initialized by ReadMta
*/
global symbol mta = nil;
/**
* If true, don't run SuSEconfig or restart the services.
* Autoinstall uses this to do all in one place.
*/
global boolean write_only = false;
boolean create_config = false;
/**
* If MAIL_CREATE_CONFIG is not yes, the user
* does not want SuSEconfig to modify sendmail.cf/main.cf.
* So we will warn him before setting it to yes.
* @return Is it yes?
*/
global define boolean CreateConfig () ``{
return create_config;
}
/**
* `permanent, `dialup or `none
*/
global symbol connection_type = `permanent;
/**
* If false, port 25 will listen only for localhost
*/
global boolean listen_remote = false;
/**
* Use a virus scanner (AMaViS).
* amavisd-new (mta-independent) must be installed.
* It will be installed if amavis_allowed and it is not installed.
*/
global boolean use_amavis = false;
/**
* Is amavis available on the installation media?
*/
global boolean amavis_allowed = true;
/**
* Domains for locally delivered mail.
* (ahost.acompany.com is a domain)
*/
global list<string> local_domains = [];
/**
* A relay server for outgoing mail.
* May be enclosed in [brackets] to prevent MX lookups.
*/
global string outgoing_mail_server = "";
/**
* Do the MTA use TLS for sending the email.
*/
global string smtp_use_TLS = "yes";
/**
* Mail will appear to come from this domain. Applies also for the
* envelope. Does not apply for mail from root.
*/
global string from_header = "";
/**
* If empty, from_header will be applied to mails coming from
* local_domains, otherwise from these domains. (Remember: mail
* domains)
*/
global list<string> masquerade_other_domains = [];
/**
* User specific sender masquerading.
* List of maps: $[comment:, user:, address:] (all are strings)
*/
global list<map> masquerade_users = [];
/**
* sysconfig/postfix:POSTFIX_MDA
* #26052
*/
global symbol postfix_mda = `local;
/**
* When should fetchmail run:
* <dl>
* <dt> "manual" <dd>
* <dt> "daemon" <dd>
*/
global string fetchmail_mode = "manual";
/**
*List of maps:
* $[server:, protocol:, remote_user:, local_user:, password:,
* enabled:(bool), other_(server|client)_options: ]
*/
global list<map> fetchmail = [];
/**
* Domain-specific aliases.
* List of maps: $[comment:, alias:, destinations:] (all are strings)
*/
global list<map> virtual_users = [];
/**
* SMTP AUTH (#23000)
* list of maps:
* The ui only handles the first list item, the rest is for autoyast
* $[server: string, user: string, password: string(plain text)]
* There are other map keys that must be preserved on editing.
*/
global list<map> smtp_auth = [];
/**
* Sysconfig setting that enables the feature.
* For postfix, it is a simple yes/no which we set to (size(smtp_auth)>0)
* For sendmail, it is a list of methods which we set to empty or all
* but we don't touch it if it was something in between, marked as nil.
* Must default to non-nil.
*/
boolean enable_smtp_auth = false;
/* ---------------------------------------------------------------- */
// constants
/**
* The full set of authentication mechanisms for sendmail
*/
string sendmail_all_mechanisms = "plain gssapi digest-md5 cram-md5";//const
/**
* Fetchmail protocols, as defined in rcfile_l.l
* Probably not all of them are compatible with our simplified scheme
* but it does not hurt to include them.
* Must check for validity: the agent matches [[:alnum:]]+,
* lowercase names are valid too.
*/
global list<string> protocol_choices = [
"AUTO",
"POP2",
"POP3",
"IMAP",
"APOP",
"KPOP",
"SDPS",
"ETRN",
"ODMR",
];
/* ---------------------------------------------------------------- */
/**
* Has the configuration been changed?
* Can be used as an argument to Popup::ReallyAbort
*/
global boolean touched = false;
/**
* A convenient shortcut for setting touched.
* @param really if true, set Mail::touched
* @example Mail::Touch (Mail::var != ui_var);
*/
global define void Touch (boolean really) ``{
touched = touched || really;
}
/* ---------------------------------------------------------------- */
/**
* Read only, set by ProbePackages.
* Use as an argument to Package::DoInstallAndRemove
*/
global list<string> install_packages = [];
/**
* Read only, set by ProbePackages.
* Use as an argument to Package::DoInstallAndRemove
*/
global list<string> remove_packages = [];
/**
* Of the four available amavis packages, amavis-postfix does not need
* a service running, others do.
* Update: only one package, amavisd-new, but let's keep the variable,
* just in case.
* We query rpm in WriteGeneral (so that it works for autoinst too).
* This is only used if use_amavis is on, of course.
*/
boolean amavis_service = true;
/**
* The cron file name for the queue checking.
*/
global string cron_file = "/etc/cron.d/novell.postfix-check-mail-queue";
/**
* The cron interval for the queue checking.
*/
global integer check_interval = 15;
/**
* Detect which packages have to be installed
* and return a descriptive string for a plain text pop-up.
* @return "" or "Foo will be installed.\nBar will be installed.\n"
*/
global define string ProbePackages () ``{
string message = "";
install_packages = [];
remove_packages = [];
if (use_amavis)
{
string pkg = "amavisd-new";
if (! Package::Installed (pkg))
{
install_packages = add (install_packages, pkg);
// Translators: popup message part, ends with a newline
message = message + _("AMaViS, a virus scanner, will be installed.\n");
}
if (! Package::Installed ("clamav"))
{
// #115295
// Amavis alone will block incoming mail if no scanner is found
// We ship clamav but not on opensuse
// Clamav can work without clamav-db.rpm if set up manually
// so we do not check Installed "clamav-db"
y2milestone ("clamav not installed");
if (! Package::AvailableAll (["clamav", "clamav-db"]))
{
// error popup.
Report::Error (_("AMaViS needs a virus scanner such as ClamAV
to do the actual scanning, but ClamAV was not found.
Configure a scanner manually."));
}
else
{
install_packages = add (install_packages, "clamav");
install_packages = add (install_packages, "clamav-db");
}
}
}
if (size (fetchmail) > 0 && ! Package::Installed ("fetchmail"))
{
install_packages = add (install_packages, "fetchmail");
// Translators: popup message part, ends with a newline
message = message + _("Fetchmail, a mail downloading utility, will be installed.\n");
}
if ((postfix_mda == `cyrus) &&
! Package::Installed("cyrus-imapd"))
{
install_packages = add(install_packages,"cyrus-imapd");
// Translators: popup message part, ends with a newline
message = message + _("Cyrus-imapd, an IMAP server, will be installed.\n");
}
if( install_packages != [] )
{
Package::DoInstall(install_packages);
}
return message;
}
/* ---------------------------------------------------------------- */
/**
* Detect the MTA installed
*/
define void ReadMta () ``{
// so that AY cloning works, #45071
y2milestone ("========== Reading MTA ==========");
if (PackageSystem::Installed ("sendmail"))
{
mta = `sendmail;
}
else if (PackageSystem::Installed ("postfix"))
{
mta = `postfix;
}
else
{
mta = `other;
}
y2milestone ("Read MTA: %1", mta);
}
/**
* @return Whether rcfetchmail should run
*/
define boolean RunFetchmailGlobally () ``{
return ( fetchmail_mode == "daemon" && size (fetchmail) > 0 );
}
/**
* Read all mail settings from the SCR
* @param abort A block that can be called by Read to find
* out whether abort is requested. Returns true if abort
* was pressed.
* @return True on success
*/
global define boolean Read (block<boolean> abort) ``{
// Translators: dialog caption
string caption = _("Initializing mail configuration");
Progress::New (caption, " ", 0, [
// Translators: progress label
// do not translate MTA
_("Determining Mail Transport Agent (MTA)"),
// Translators: progress label
_("Reading general settings"),
// Translators: progress label
_("Reading masquerading settings"),
// Translators: progress label
_("Reading downloading settings"),
// Translators: progress label
_("Reading alias tables"),
// Translators: progress label
// smtp-auth
_("Reading authentication settings..."),
],
[], "");
// announce 1
Progress::NextStage ();
if (eval (abort))
{
return false;
}
// read 1
ReadMta ();
if (mta == `other)
{
return false;
}
// announce 2
Progress::NextStage ();
if (eval (abort))
{
return false;
}
// read 2
// create_config
create_config = SCR::Read (.sysconfig.mail.MAIL_CREATE_CONFIG)== "yes";
// open port
listen_remote = SCR::Read (.sysconfig.mail.SMTPD_LISTEN_REMOTE)=="yes";
boolean progress_orig = Progress::set (false);
SuSEFirewall::Read ();
Progress::set (progress_orig);
// connection_type:
boolean nc = false;
boolean ex = false;
boolean nd = false;
// the service must be always running
//boolean service = false;
if (mta == `sendmail)
{
nc = SCR::Read (.sysconfig.sendmail.SENDMAIL_NOCANONIFY) == "yes";
ex = SCR::Read (.sysconfig.sendmail.SENDMAIL_EXPENSIVE) == "yes";
}
else if (mta == `postfix)
{
nc = SCR::Read (.sysconfig.postfix.POSTFIX_NODNS) == "yes";
ex = SCR::Read (.sysconfig.postfix.POSTFIX_DIALUP) == "yes";
nd = SCR::Read (.sysconfig.postfix.POSTFIX_NODAEMON) == "yes";
}
else
{
return false;
}
if (nd)
{
connection_type = `nodaemon;
}
else if (nc)
{
connection_type = (ex)? `dialup : `none;
}
else
{
connection_type = `permanent;
}
// amavis
string amavis_pkg = "amavisd-new";
amavis_allowed = PackageSystem::Installed (amavis_pkg) ||
Mode::commandline ();
// || PackageSystem::Available (amavis_pkg);
use_amavis = amavis_allowed && (SCR::Read (.sysconfig.amavis.USE_AMAVIS) == "yes");
// local_domains
string ld_s = "";
if (mta == `sendmail)
{
ld_s = (string) SCR::Read (.sysconfig.sendmail.SENDMAIL_LOCALHOST);
}
else if (mta == `postfix)
{
ld_s = (string) SCR::Read (.sysconfig.postfix.POSTFIX_LOCALDOMAINS);
}
else
{
return false;
}
local_domains = filter (string s, splitstring(ld_s, " ,;"),``(s != ""));
// outgoing_mail_server
if (mta == `sendmail)
{
outgoing_mail_server = (string)
SCR::Read (.sysconfig.sendmail.SENDMAIL_SMARTHOST);
}
else if (mta == `postfix)
{
smtp_use_TLS = (string) SCR::Read (.sysconfig.postfix.POSTFIX_SMTP_TLS_CLIENT);
outgoing_mail_server = (string)
SCR::Read (.sysconfig.postfix.POSTFIX_RELAYHOST);
}
else
{
return false;
}
// postfix_mda
if (mta == `postfix)
{
string postfix_mda_s = (string)
SCR::Read (.sysconfig.postfix.POSTFIX_MDA);
if (postfix_mda_s == "local")
{
postfix_mda = `local;
}
else if (postfix_mda_s == "procmail")
{
postfix_mda = `procmail;
}
else if (postfix_mda_s == "cyrus")
{
postfix_mda = `cyrus;
}
else
{
postfix_mda = nil;
}
}
// announce 3
Progress::NextStage ();
if (eval (abort))
{
return false;
}
// read 3
// from_header
from_header = (string) SCR::Read (.sysconfig.mail.FROM_HEADER);
// handle nonexistent file
if (from_header == nil)
{
from_header = "";
}
// masquerade_other_domains
string mod_s = "";
if (mta == `sendmail)
{
mod_s = (string) SCR::Read (.sysconfig.sendmail.MASQUERADE_DOMAINS);
}
else if (mta == `postfix)
{
mod_s = (string) SCR::Read (.sysconfig.postfix.POSTFIX_MASQUERADE_DOMAIN);
}
else
{
return false;
}
masquerade_other_domains = filter (string s, splitstring (mod_s, " ,;"),
``(s != ""));
// masquerade_users
list<map> mu_raw = [];
if (mta == `sendmail)
{
mu_raw = MailTable::Read ("sendmail.generics");
}
else if (mta == `postfix)
{
mu_raw = MailTable::Read ("postfix.sendercanonical");
}
else
{
return false;
}
masquerade_users = maplist (map e, mu_raw,
``($[
"comment" : e["comment"]: "",
"user" : e["key"]: "",
"address" : e["value"]: "",
]));
// announce 4
Progress::NextStage ();
if (eval (abort))
{
return false;
}
if( Service::Enabled ("fetchmail") )
{
fetchmail_mode = "daemon";
}
// if we are testing as non-root, it will fail, that's OK
map out = (map) SCR::Execute (.target.bash_output, "/usr/bin/id --user");
boolean root = out["stdout"]:"" == "0\n";
fetchmail = (list<map>) SCR::Read (.mail.fetchmail.accounts);
if (fetchmail == nil && root)
{
// Translators: error message,
// %1 is a file name,
// %2 is a long file name - leave it on a separate line
Report::Error (sformat(_("Error reading file %1. The file must have
a fixed format to be readable by YaST. For details, see
%2"),
"/etc/fetchmailrc",
"/usr/share/doc/packages/yast2-mail/fetchmailrc.txt"));
return false;
}
//TODO what to do with a difficult syntax etc?
// announce 5
Progress::NextStage ();
if (eval (abort))
{
return false;
}
// read 5
// MailAliases::merge_aliases = false;
// aliases
if (!MailAliases::ReadAliases ())
{
return false;
}
// virtual_users
list<map> v_raw = [];
if (mta == `sendmail)
{
v_raw = MailTable::Read ("sendmail.virtuser");
}
else if (mta == `postfix)
{
v_raw = MailTable::Read ("postfix.virtual");
}
else
{
return false;
}
virtual_users = maplist (map e, v_raw,
``($[
"comment" : e["comment"]: "",
"alias" : e["key"]: "",
"destinations" : e["value"]: "",
]));
// announce 6
Progress::NextStage ();
if (eval (abort))
{
return false;
}
// read 6
if (mta == `sendmail)
{
smtp_auth = (list<map>) SCR::Read (.mail.sendmail.auth.accounts);
string mechanisms =
(string) SCR::Read (.sysconfig.sendmail.SMTP_AUTH_MECHANISMS);
if (mechanisms != sendmail_all_mechanisms && mechanisms != "")
{
enable_smtp_auth = nil;
}
}
else if (mta == `postfix)
{
smtp_auth = (list<map>) SCR::Read (.mail.postfix.auth.accounts);
}
else
{
return false;
}
// complete
Progress::NextStage ();
return true;
}
/**
* Wrapper for global Read function, without the callback argument
*/
global boolean ReadWithoutCallback () {
block<boolean> abort_block = ``{ return false; };
return Read (abort_block);
}
/**
* Make up data for screnshots
*/
global define void Fake () ``{
mta = `postfix;
create_config = true;
listen_remote = true;
connection_type = `dialup;
amavis_allowed = true;
use_amavis = true;
// good example?
local_domains = ["branch1.example.com", "branch2.example.com"];
outgoing_mail_server = "mail.example.com";
from_header = "example.com";
masquerade_other_domains = [];
masquerade_users = [
$["user": "hyde", "address": "DrJekyll@Example.com"],
];
fetchmail = [
$[
"server": "pop3.example.net",
"protocol": "POP3",
"remote_user": "jekyll",
"local_user": "hyde",
"password": "stephenson",
],
];
// just patch out root
MailAliases::ReadAliases ();
MailAliases::root_alias = "hyde";
// TODO virtual
enable_smtp_auth = true;
smtp_auth = [
$[
"server": "mail.example.com",
"user": "jekyll",
"password": "foo"
],
];
}
/**
* Part of Write.
* @return success
*/
global define boolean WriteGeneral () ``{
// create_config
// if the user wanted it false, we did not proceed
SCR::Write (.sysconfig.mail.MAIL_CREATE_CONFIG, "yes");
// listen_remote
SCR::Write (.sysconfig.mail.SMTPD_LISTEN_REMOTE,
listen_remote? "yes":"no");
boolean progress_orig = Progress::set (false);
SuSEFirewall::WriteOnly ();
Progress::set (progress_orig);
// connection_type
// nocanonify/nodns
// expensive/dialup
path nc_nd = nil;
path ex_di = nil;
string service = nil;
if (mta == `sendmail)
{
nc_nd = .sysconfig.sendmail.SENDMAIL_NOCANONIFY;
ex_di = .sysconfig.sendmail.SENDMAIL_EXPENSIVE;
service = "sendmail";
}
else if (mta == `postfix)
{
nc_nd = .sysconfig.postfix.POSTFIX_NODNS;
ex_di = .sysconfig.postfix.POSTFIX_DIALUP;
service = "postfix";
}
else
{
return false;
}
if (connection_type == `nodaemon)
{
SCR::Write (.sysconfig.postfix.POSTFIX_NODAEMON, "yes");
SCR::Write (nc_nd, "yes");
SCR::Write (ex_di, "no");
}
else if (connection_type == `permanent)
{
SCR::Write (.sysconfig.postfix.POSTFIX_NODAEMON, "no");
SCR::Write (nc_nd, "no");
SCR::Write (ex_di, "no");
}
else if (connection_type == `dialup)
{
SCR::Write (.sysconfig.postfix.POSTFIX_NODAEMON, "no");
SCR::Write (nc_nd, "yes");
SCR::Write (ex_di, "yes");
}
else if (connection_type == `none)
{
SCR::Write (.sysconfig.postfix.POSTFIX_NODAEMON, "no");
SCR::Write (nc_nd, "yes");
SCR::Write (ex_di, "no");
}
else
{
y2internal("Unrecognized connection_type: %1", connection_type);
return false;
}
if (connection_type == `nodaemon)
{
Service::Disable (service);
SCR::Write (.sysconfig.amavis.USE_AMAVIS, "no");
SCR::Write (.target.string,cron_file,"-*/"+check_interval+" * * * * root /usr/sbin/check_mail_queue &>/dev/null");
}
else
{
SCR::Execute (.target.bash,"test -e "+cron_file+" && rm "+cron_file+";");
Service::Enable (service);
Service::Adjust ("amavis", use_amavis? "enable":"disable");
}
// amavis
SCR::Write (.sysconfig.amavis.USE_AMAVIS, use_amavis? "yes":"no");
// used also in WriteServices
amavis_service = true;
// SENDMAIL_ARGS
// by default they contain -q30m, not good for dial-up
// SENDMAIL_CLIENT_ARGS must contain -q... or it will not run!
if (mta == `sendmail)
{
string default_permanent = "-L sendmail -Am -bd -q30m -om";
string default_dialup = "-L sendmail -Am -bd -om";
string args = (string) SCR::Read (.sysconfig.sendmail.SENDMAIL_ARGS);
if (connection_type == `permanent && args == default_dialup)
{
SCR::Write (.sysconfig.sendmail.SENDMAIL_ARGS, default_permanent);
}
else if (connection_type == `dialup &&
// if empty, sendmail init-script uses the default
(args == default_permanent || args == ""))
{
SCR::Write (.sysconfig.sendmail.SENDMAIL_ARGS, default_dialup);
}
}
// local_domains
if (mta == `sendmail)
{
string ld_s = mergestring (local_domains, " ");
SCR::Write (.sysconfig.sendmail.SENDMAIL_LOCALHOST, ld_s);
}
else if (mta == `postfix)
{
string ld_s = mergestring (local_domains, ","); // noted in #12672
SCR::Write (.sysconfig.postfix.POSTFIX_LOCALDOMAINS, ld_s);
}
else
{
return false;
}
// outgoing_mail_server
if (mta == `sendmail)
{
SCR::Write (.sysconfig.sendmail.SENDMAIL_SMARTHOST, outgoing_mail_server);
}
else if (mta == `postfix)
{
if( smtp_use_TLS != "no" )
{
string oms = outgoing_mail_server;
string oms_no_brackets = regexpmatch (oms, "[[][^][]*[]]:.*") ? regexpsub (oms, ".(.*).:.*", "\\1") : oms;
string oms_port = regexpmatch (oms, "[[][^][]*[]]:.*") ? regexpsub (oms, ".*.:(.*)", "\\1") : "";
if( oms_no_brackets == oms )
{
oms_no_brackets = regexpmatch (oms, "[[][^][]*[]]") ? regexpsub (oms, ".(.*).", "\\1") : oms;
}
if( oms_no_brackets == oms )
{
oms_no_brackets = regexpmatch (oms, ".*:.*") ? regexpsub (oms, "(.*):.*", "\\1") : oms;
oms_port = regexpmatch (oms, ".*:.*") ? regexpsub (oms, ".*:(.*)", "\\1") : "";
}
if( oms_port != "" )
{
outgoing_mail_server = "[" + oms_no_brackets + "]:" + oms_port;
}
else
{
outgoing_mail_server = "[" + oms_no_brackets + "]";
}
}
SCR::Write (.sysconfig.postfix.POSTFIX_RELAYHOST, outgoing_mail_server);
SCR::Write (.sysconfig.postfix.POSTFIX_SMTP_TLS_CLIENT, smtp_use_TLS);
}
else
{
return false;
}
// postfix_mda
if (mta == `postfix)
{
string s_mda = "local"; // default to local
if (postfix_mda == `procmail)
{
s_mda = "procmail";
}
else if (postfix_mda == `cyrus)
{
s_mda = "cyrus";
}
SCR::Write (.sysconfig.postfix.POSTFIX_MDA, s_mda);
}
return true;
}
/**
* Part of Write.
* @return success
*/
global define boolean WriteMasquerading () ``{
// from_header
SCR::Write (.sysconfig.mail.FROM_HEADER, from_header);
// masquerade_other_domains
if (mta == `sendmail)
{
string mod = mergestring (masquerade_other_domains, " ");
SCR::Write (.sysconfig.sendmail.MASQUERADE_DOMAINS, mod);
}
else if (mta == `postfix)
{
string mod = mergestring (masquerade_other_domains, ",");
SCR::Write (.sysconfig.postfix.POSTFIX_MASQUERADE_DOMAIN, mod);
}
else
{
return false;
}
// masquerade_users
list<map> mu_raw = maplist (map e, masquerade_users,
``($[
"comment" : e["comment"]:"",
// TODO check that nonempty
"key" : e["user"]:"",
"value" : e["address"]:"",
]));
if (mta == `sendmail)
{
MailTable::Write ("sendmail.generics", mu_raw);
}
else if (mta == `postfix)
{
MailTable::Write ("postfix.sendercanonical", mu_raw);
}
else
{
return false;
}
return true;
}
/**
* Part of Write.
* @return success
*/
global define boolean WriteDownloading () ``{
// fetchmail
// TODO ?other settings: autofetch? at device up?
SCR::Write (.mail.fetchmail.accounts, fetchmail);
if (! SCR::Write (.mail.fetchmail, nil))
{
// Translators: error message
Report::Error (_("Error writing the fetchmail configuration."));
return false;
}
if (RunFetchmailGlobally ())
{
Service::Enable ("fetchmail");
}
else
{
Service::Disable ("fetchmail");
}
return true;
}
/**
* Part of Write.
* @return success
*/
global define boolean WriteAliasesAndVirtual () ``{
// aliases
if (! MailAliases::WriteAliases ())
{
return false;
}
// virtual_users
list<map> v_raw = maplist (map e, virtual_users,
``($[
"comment" : e["comment"]:"",
"key" : e["alias"]:"",
"value" : e["destinations"]:"",
]));
if (mta == `sendmail)
{
MailTable::Write ("sendmail.virtuser", v_raw);
}
else if (mta == `postfix)
{
MailTable::Write ("postfix.virtual", v_raw);
}
else
{
return false;
}
return true;
}
/**
* Part of Write.
* @return success
*/
global define boolean WriteSmtpAuth () ``{
// TODO how to remove the only entry?
// filter it out in the dialog?
if (enable_smtp_auth != nil)
{
enable_smtp_auth = size (smtp_auth) > 0;
}
if ( smtp_auth[0,"server"]:"" != outgoing_mail_server )
{
smtp_auth[0,"server"]=outgoing_mail_server;
}
if (mta == `sendmail)
{
SCR::Write (.mail.sendmail.auth.accounts, smtp_auth);
if (enable_smtp_auth != nil)
{
SCR::Write (.sysconfig.sendmail.SMTP_AUTH_MECHANISMS,
enable_smtp_auth? sendmail_all_mechanisms: "");
}
}
else if (mta == `postfix)
{
SCR::Write (.mail.postfix.auth.accounts, smtp_auth);
SCR::Write (.sysconfig.postfix.POSTFIX_SMTP_AUTH,
enable_smtp_auth? "yes": "no");
}
else
{
return false;
}
return true;
}
/**
* Part of Write.
* @return success
*/
global define boolean WriteFlush () ``{
//flush the agents
map<string, path> paths = $[
"/etc/sysconfig/mail": .sysconfig.mail,
"/etc/sysconfig/amavis": .sysconfig.amavis,
];
list<string> tables = nil;
if (mta == `sendmail)
{
paths["/etc/sysconfig/sendmail"] = .sysconfig.sendmail;
paths["/etc/mail/auth/auth-info"] = .mail.sendmail.auth;
tables = [
"sendmail.generics",
"aliases",
"sendmail.virtuser",
];
}
else if (mta == `postfix)
{
paths["/etc/sysconfig/postfix"] = .sysconfig.postfix;
paths["/etc/postfix/sasl_passwd"] = .mail.postfix.auth;
tables = [
"postfix.sendercanonical",
"aliases",
"postfix.virtual",
];
}
else
{
return false;
}
foreach (string filename, path p, paths, ``{
if (!SCR::Write (p, nil))
{
// Translators: error message
Report::Error (sformat (_("Error writing file %1"), filename));
return false;
}
});
foreach (string p, tables, ``{
if (!MailTable::Flush (p))
{
string filename = MailTable::FileName (p);
// Translators: error message
Report::Error (sformat (_("Error writing file %1"), filename));
return false;
}
});
return true;
}
/**
* Part of Write.
* @return success
*/
global define boolean WriteSuSEconfig () ``{
//run SuSEconfig with the necessary modules
// TODO other modules using FROM_HEADER?
integer ret = 0;
if (mta == `sendmail)
{
ret = (integer)
SCR::Execute(.target.bash,"/sbin/SuSEconfig --module sendmail");
}
else if (mta == `postfix)
{
ret = (integer)
SCR::Execute(.target.bash, "/sbin/SuSEconfig --module postfix");
}
else
{
return false;
}
if (ret != 0)
{
// Translators: error message
Report::Error (_("Error running SuSEconfig."));
return false;
}
return true;
}
/**
* Part of Write.
* @return success
*/
global define boolean WriteServices () ``{
if (amavis_service)
{
Service::Stop ("amavis");
if (use_amavis)
{
if (!Service::Start ("amavis"))
{
// Translators: error message
Report::Error (sformat (_("Error starting service %1."), "amavis"));
return false;
}
}
}
Service::Stop ("fetchmail");
if (RunFetchmailGlobally ())
{
if (!Service::Start ("fetchmail"))
{
// Translators: error message
Report::Error (sformat (_("Error starting service %1."), "fetchmail"));
return false;
}
}
string service = "";
if (mta == `sendmail)
{
service = "sendmail";
}
else if (mta == `postfix)
{
service = "postfix";
}
else
{
return false;
}
if (!Service::Restart (service))
{
// Translators: error message
Report::Error (sformat (_("Error starting service %1."), service));
return false;
}
// ServiceAdjust enable/disable is done in WriteGeneral
return SuSEFirewall::ActivateConfiguration ();
}
/**
* Update the SCR according to mail settings
* @param abort A block that can be called by Write to find
* out whether abort is requested. Returns true if abort
* was pressed.
* @return True on success
*/
global define boolean Write (block<boolean> abort) ``{
list<list> stages = [
// Translators: progress label
[ _("Writing general settings"), WriteGeneral ],
];
if (connection_type != `none)
{
// Translators: progress label
stages = add (stages, [ _("Writing masquerading settings"), WriteMasquerading ]);
// Translators: progress label
stages = add (stages, [ _("Writing alias tables"), WriteAliasesAndVirtual ]);
// Write them unconditionally, because it is now possible to
// enter them also in the Permanent mode. Bug #17417.
// Translators: progress label
if (size (fetchmail) > 0 || Package::Installed ("fetchmail"))
{
stages = add (stages, [ _("Writing downloading settings"), WriteDownloading ]);
}
// Translators: progress label
stages = add (stages, [ _("Writing authentication settings..."), WriteSmtpAuth ]);
}
// Translators: progress label
stages = add (stages, [ _("Finishing writing configuration files"), WriteFlush ]);
// autoinstallation does it all together later
if (! write_only)
{
// Translators: progress label
stages = add (stages, [ _("Running SuSEconfig"), WriteSuSEconfig ]);
// Translators: progress label
stages = add (stages, [ _("Restarting services"), WriteServices ]);
}
// Translators: dialog caption
string caption = _("Saving mail configuration");
// We do not set help text here, because it was set outside
Progress::New (caption, " ", 0, maplist (list e, stages, ``(e[0]:"")), [], "");
foreach (list e, stages, ``{
Progress::NextStage ();
if (eval (abort))
{
// TODO: finishes only this iteration, not the function
return false;
}
any af = e[1]:nil;
boolean() f = (boolean ()) af;
if (! f ())
{
// TODO: finishes only this iteration, not the function
return false;
}
});
// complete
Progress::NextStage ();
return true;
}
/**
* Wrapper for global Write function, without the callback argument
*/
global boolean WriteWithoutCallback () {
block<boolean> abort_block = ``{ return false; };
return Write (abort_block);
}
/**
* Get all mail settings from the first parameter
* (For use by autoinstallation.)
* @param Settings The YCP structure to be imported.
* @return True on success
*/
global define boolean Import (map Settings) ``{
map<string,any> settings = (map<string,any>) Settings;
y2debug ("before %1", settings); // may contain passwords
settings = mapmap(string k, any v, settings,``{
if (k == "mta" && is(v,symbol)) {
return($[k : v]);
} else if (k == "connection_type" && is(v,symbol)) {
return($[k : v]);
} else if (k == "postfix_mda" && is(v,symbol)) {
return($[k : v]);
}
if (k == "mta" && v == "sendmail") {
return($["mta" : `sendmail]);
} else if (k == "mta" && v == "postfix") {
return($["mta" : `postfix]);
} else if (k == "mta") {
return($["mta" : `other]);
} else if (k == "connection_type" && v == "permanent") {
return($["connection_type" : `permanent]);
} else if (k == "connection_type" && v == "dialup") {
return($["connection_type" : `dialup]);
} else if (k == "connection_type") {
return($["connection_type" : `none]);
} else if (k == "postfix_mda" && v == "local") {
return($["postfix_mda" : `local]);
} else if (k == "postfix_mda" && v == "procmail") {
return($["postfix_mda" : `procmail]);
} else if (k == "postfix_mda") {
return($["postfix_mda" : `cyrus]);
} else {
return ($[k : v]);
}
});
mta = settings["mta"]: `other;
connection_type = settings["connection_type"]: `none;
listen_remote = settings["listen_remote"]: false;
use_amavis = settings["use_amavis"]: false;
local_domains = settings["local_domains"]: [];
outgoing_mail_server = settings["outgoing_mail_server"]: "";
postfix_mda = settings["postfix_mda"]: `local;
from_header = settings["from_header"]: "";
masquerade_other_domains = settings["masquerade_other_domains"]: [];
masquerade_users = settings["masquerade_users"]: [];
fetchmail = settings["fetchmail"]: [];
MailAliases::aliases = settings["aliases"]: [];
MailAliases::FilterRootAlias ();
// MailAliases::merge_aliases = settings["merge_aliases"]: false;
virtual_users = settings["virtual_users"]: [];
smtp_use_TLS = settings["smtp_use_TLS"]: "yes";
smtp_auth = settings["smtp_auth"]: [];
y2debug ("after %1", settings); // may contain passwords
return true;
}
/**
* Dump the mail settings to a single map
* (For use by autoinstallation.)
* @return Dumped settings (later acceptable by Import ())
*/
global define map Export () ``{
map<string,any> settings = $[
"mta": mta,
"connection_type": connection_type,
"listen_remote": listen_remote,
"use_amavis": use_amavis,
"local_domains": local_domains,
"outgoing_mail_server": outgoing_mail_server,
"from_header": from_header,
"masquerade_other_domains": masquerade_other_domains,
"masquerade_users": masquerade_users,
"fetchmail": fetchmail,
"aliases": MailAliases::MergeRootAlias (MailAliases::aliases),
// "merge_aliases": MailAliases::merge_aliases,
"virtual_users": virtual_users,
"smtp_auth": smtp_auth,
"smtp_use_TLS": smtp_use_TLS,
];
if (mta == `postfix)
{
settings = add (settings, "postfix_mda", postfix_mda);
}
// Dont export empty fields
foreach (string k, any v, settings, ``{
if (contains ([ "", nil, [], $[] ], v))
{
settings = remove(settings, k);
}
});
return settings;
}
/**
* Summarizes a list of data
* @param title passed to Summary::AddHeader
* @param value a list (of scalars, lists or maps)
* @param index if the entries are not scalars,
* use this index to get a scalar
* @return Summary-formatted description
*/
define string ListItem(string title, any value, any index) ``{
string summary = "";
summary = Summary::AddHeader(summary, title);
if (is(value,list) && value != nil && value != []) {
summary = Summary::OpenList(summary);
foreach (any d, (list) value, ``{
string entry = "";
if (is(d,map))
entry = ((map)d)[index]:"???";
else if (is (d,list))
entry = ((list)d)[(integer)index]:"???";
else
entry = (string) d;
summary = Summary::AddListItem(summary, entry);
});
summary = Summary::CloseList(summary);
} else {
summary = Summary::AddLine(summary,Summary::NotConfigured ());
}
return summary;
}
/**
* Summary
* @return string with summary of configuration
*/
global define string Summary ()
``{
// TODO: use widget captions, strip sho&rtcuts
string agent = "";
if (mta == `sendmail)
// MTA used: Sendmail
// Not translated
agent = "Sendmail";
else if (mta == `postfix)
// MTA used: Postfix
// Not translated
agent = "Postfix";
else
// MTA used: other than Sendmail or Postfix
agent = _("Other");
string con_type = "";
if (connection_type == `permanent)
// summary: connection type
con_type = _("Permanent");
else if (connection_type == `dialup)
// summary: connection type
con_type = _("Dial-up");
else
// summary: connection type
con_type = _("None");
string nc = Summary::NotConfigured ();
string summary = "";
// summary header; mail transfer agent
summary = Summary::AddHeader(summary, _("MTA"));
summary = Summary::AddLine(summary, agent);
// summary header
summary = Summary::AddHeader(summary, _("Connection Type"));
summary = Summary::AddLine(summary,con_type );
// summary header
summary = Summary::AddHeader(summary, _("Outgoing Mail Server"));
summary = Summary::AddLine(summary, (outgoing_mail_server != "") ? outgoing_mail_server : nc);
// summary header; the "From: foo@bar.com" mail header
summary = Summary::AddHeader(summary, _("From Header"));
summary = Summary::AddLine(summary, (from_header != "") ? from_header : nc);
// summary item
summary = summary + ListItem (_("Local Domains"), local_domains, nil);
// summary item
summary = summary + ListItem (_("Masquerade Other Domains"), masquerade_other_domains, nil);
// summary item
summary = summary + ListItem (_("Masquerade Users"), masquerade_users, "user");
// summary header
summary = Summary::AddHeader(summary, _("Accept remote SMTP connections"));
summary = Summary::AddLine(summary, (listen_remote) ?
// summary item
_("Yes") :
// summary item
_("No"));
// summary header
summary = Summary::AddHeader(summary, _("Use AMaViS"));
summary = Summary::AddLine(summary, (use_amavis) ?
// summary item
_("Yes") :
// summary item
_("No"));
// summary item
summary = summary + ListItem (_("Fetchmail"), fetchmail, "server");
// summary item
summary = summary + ListItem (_("Aliases"), MailAliases::MergeRootAlias (MailAliases::aliases), "alias");
// summary item
summary = summary + ListItem (_("Virtual Users"), virtual_users, "alias");
// summary item
summary = summary + ListItem (_("Authentication"), smtp_auth, "server");
return summary;
}
/**
* Return required packages for auto-installation
* @return map of packages to be installed and to be removed
*/
global define map AutoPackages() ``{
return ($["install": required_packages, "remove": []]);
}
}
ACC SHELL 2018