diff --git a/config.inc.php b/config.inc.php index 2011d1cd..bf41e189 100644 --- a/config.inc.php +++ b/config.inc.php @@ -538,6 +538,11 @@ function x_struct_admin_modify($struct) { // address is legal by performing a name server look-up. $CONF['emailcheck_resolve_domain']='YES'; +// When creating mailboxes or aliases, check that the domain-part of the +// address is local and managed by postfixadmin, preventing remote domains +// from being the destination for an alias +$CONF['emailcheck_localaliasonly']='NO'; + // Use TOTP for logging into Postfixadmin, can be overridden for listed // IPs to allow access by software that provide their own checking. // Exceptions can be of user, domain or global scope. @@ -548,21 +553,14 @@ function x_struct_admin_modify($struct) { // password in another system. These passwords can not access Postfixadmin. $CONF['app_passwords'] = 'NO'; -// -// -// OpenDKIM stuff -// -// +// OpenDKIM stuff // Enable the dkim database component $CONF['dkim'] = 'NO'; - // Allow regular admins to add/edit/remove dkim entries $CONF['dkim_all_admins'] = 'NO'; - -// // End OpenDKIM stuff -// + // Optional: // Analyze alias gotos and display a colored block in the first column diff --git a/functions.inc.php b/functions.inc.php index 3904fd5c..16d5288d 100644 --- a/functions.inc.php +++ b/functions.inc.php @@ -303,6 +303,33 @@ function check_domain($domain) return ''; } +/** + * Checks if a domain is local + * @param string $domain + * @return string empty if the domain is valid, otherwise string with the errormessage + */ +function check_localaliasonly($domain) { + // If emailcheck_localaliasonly is set to 'YES', disallow aliases to remote servers (but allow aliases on this server) + if (Config::bool('emailcheck_localaliasonly')) { + // get the domain part of the e-mail + list(/*NULL*/, $domain) = explode('@', $domain); + + // get all domains managed on this system by postfixadmin + $domains = list_domains(); + + // Only allow local domains to be alias destinations + if (in_array($domain, $domains)) { + return ''; + } else { + // FIXME: Add transaltions + return sprintf("You may only make aliases to domains hosted on this server. %s is a remote domain name.", htmlentities($domain)); + } + } else { + return ''; + } + +} + /** * Get password expiration value for a domain * @param string $domain - a string that may be a domain diff --git a/model/AliasHandler.php b/model/AliasHandler.php index b24b71d5..0c172914 100644 --- a/model/AliasHandler.php +++ b/model/AliasHandler.php @@ -412,12 +412,20 @@ protected function _validate_goto($field, $val) if ($domain_check != '') { $errors[] = "$singlegoto: $domain_check"; } + $localaliasonly_check = check_localaliasonly($domain); + if ($localaliasonly_check != '') { + $errors[] = "$singlegoto: $localaliasonly_check"; + } } else { $email_check = check_email($singlegoto); // preg_match -> allows for redirect to a local system account. if ($email_check != '' && !preg_match('/^[a-z0-9]+$/', $singlegoto)) { $errors[] = "$singlegoto: $email_check"; } + $localaliasonly_check = check_localaliasonly($singlegoto); + if ($localaliasonly_check != '') { + $errors[] = "$singlegoto: $localaliasonly_check"; + } } if ($this->called_by != "MailboxHandler" && $this->id == $singlegoto) { // The MailboxHandler needs to create an alias that points to itself (for the mailbox)