1. ZMailer SMTP-server policy filtering rules

	At the end of this is actually the default boiler-plate file from
	the distribution pretty much as is.

	In addition to that, policy-builder.sh script adds a set of other
	things before policy filter is ready for use:

		DB/smtp-policy.src		The boilerplate
		DB/localnames		    ('= _local_names')
		DB/smtp-policy.relay.manual ('= _full_rights')
		DB/smtp-policy.relay	    ('= _full_rights')
		DB/smtp-policy.mx.manual    ('= _relaytarget')
		DB/smtp-policy.mx	    ('= _relaytarget')
		DB/smtp-policy.spam.manual  ('= _bulk_mail')
		DB/smtp-policy.spam	    ('= _bulk_mail')

	IF YOU WANT, YOU CAN MODIFY YOUR BOILER PLATE AS WELL AS YOUR
	INSTALLED POLICY-BUILDER.SH SCRIPT.  (Doing 'make install' will
	overwrite policy-builder.sh, but not  smtp-policy.src)


	Basically these various source files (when existing) are used to
	combine knowledge of valid users around us.  Some datasets have
	TWO input source files,  smtp-policy.NN  and  smtp-policy.NN.manual,
	the ".manual" is intended to be overrider of of possibly auto-
	generated data at the "plain" version of files:



	- localnames	Who we are -- ok for receiving; does not
			grant outgoing relay capability.


	- smtp-policy.relay.manual
	- smtp-policy.relay
			Who can use us as outbound relay.

			Use here
				[ip.number]/maskwidth
			for listing those senders (networks) we
			absolutely trust.  Additionally you may give
			(at the same line) some attributes as parameters
			for this key entry:
				fulltrustnet +
				trustrecipient +
				maxinsize 30000000
				filtering +/-
				ratelimitmsgs 300

			The 1st pair will accept any source address,
			and any recipient addresses that are fed to
			the server.  THIS IS FOR VERY RARE USE,
			NOTHING IS CHECKED IF THIS IS PRESENT FOR
			A GIVEN SUBNET!

			The 2nd will verify the MAIL FROM domain,
			but after that it will accept any recipient
			addresses.

			The 3rd pair sets EHLO-reported "SIZE nn"
			parameter to be limited to 30 million bytes.
			(Or to global definition, if that is in range
			 of 1 thru 'nn'.)

			The 4th pair sets explicite content-filtering
			activation/disabling ('+'/'-') for IP address
			masks given in these files.  See the comments
			in the   smtp-policy.src   about this!

			The 5th pair sets limit on how many messages
			are accepted in an  1.0-1.15  hour period.
			Excess messages (MAIL FROMs actually) are
			treated with cold shoulder ("450" code).
			If the numeric parameter value is NEGATIVE,
			then the rejection is instant and permanent
			with "550" code.


			You may also enter domains which are looked
			up for the hostname of reversed IP address,
			but it is not very wise; IP-reversal is not
			trustworthy data.  It may also cause double-
			entry/level descendance problems when two
			domain-suffixes have same ending suffix (or
			are the same)..  (Name/keyspace problem)

			We can set the "always_accept" flag at the
			source IP test, and never after.

	- smtp-policy.mx.manual
	- smtp-policy.mx
			Who really are our MX clients.

			Use this when you really know them, and don't
			want just to trust that if recipient has MX
			to you, it would be ok...
			You can substitute this knowledge with a fuzzy
			feeling by using 'acceptifmx +' attribute at
			the generic boilerplate.

			List here domain names.

			You CAN also list here all POSTMASTER addresses
			you accept email routed to:

				postmaster@local.domain
				postmaster@client.domain

			these are magic addresses that email is accepted
			to, even when everything else is blocked.

	- smtp-policy.spam.manual
	- smtp-policy.spam
			Those users & domains that are 	absolutely no-no
			for the senders, or the recipients, no matter what
			earlier analysis has shown.
			(Except for those that we absolutely trust..)



	Short usage instructions:
		- Fill in/modify related files
		- execute  MAILBIN/policy-builder.sh  script

	Testing instructions:

		You can run the smtpserver in a mode where you can
		claim to be from any address in the outside world
		you wish:

			$MAILBIN/smtpserver -i -d 1 -T '[1.2.3.4]'

		The mode must be interactive (-i), and supplying
		debug mode (-d 1) to it is good help.

		Actual claimed connection source address is to be
		given inside square brackets as a SMTP IP address
		literal.

		Now you can try things like:

			220 ...
			EHLO foo
			...
			MAIL FROM:<>
			...
			RCPT TO:<address@local.domain>
			...
			RCPT TO:<address@elsewere.domain>
			...

		(Substitute some real domains into those RCPT TO
		 lines -- "local.domain" is a hint about what to
		 pick for it..)

		Depending what kind of address you have supplied
		to the -T parameter, they get either accepted, or
		rejected.


2. RBL-type blocking lists

	Per default the system DOES NOT use RBL-type blocking lists.
	There are two ways how to take them into use: 

	-  You can start rejecting at the connection setup and then at
	   MAIL FROM (and RCPT TO). 

	   However many (especially M$ environment) SMTP clients won't
	   react on that properly, and will just keep repeating the delivery
	   attempts. 

	-  You can delay the rejections until RCPT addresses are given. 


2.1 Immediate rejection by RBL

	Like mentioned above, this method has a problem with many clients
	who don't believe that HELO can give 500-series response. 

	Method is as follows: 

	Pick your choice of databases to the second variant ``_rbl0'' label
	by joining your selection from various things exemplified here below
	by using ``:'' character as glue in between: 

	     ``+'' alias ``rbl.maps.vix.com'' 
	     ``relays.mail-abuse.org'' 
	     ``dul.maps.vix.com'' 
	     ``relays.orbs.org'' 
	     ``ok.orbs.org:relays.orbs.org'' <-- THIS IS A PAIR! 

	For the ``ok.orbs.org:relays.orbs.org'' the ZMailer 2.99.52patch2
	has special support, but it isn't entirely fool-proof thing...
	(Due to false OKs in the OK zone while NETBLOCK type things
	 exist at the RELAYS zone.)

	An example for the resulting attribute pair: (RBL+DUL+RSS) 

	  #| Second RBL variant: Early block with RBL+DUL+RSS
	  _rbl0   test-dns-rbl  +:dul.maps.vix.com:relays.mail-abuse.org
	  _rbl1   # Nothing

2.2 Delayed rejection by RBL

	Delay the rejection report to ``RCPT TO'' verbs by using the
	``Third RBL variant'': 

	  #| Third RBL variant: Late block with RBL+DUL+RSS
	  _rbl0   rcpt-dns-rbl      +:dul.maps.vix.com:relays.mail-abuse.org
	  _rbl1   test-rcpt-dns-rbl +

	The sample boilerplace will use these as defaults unless you choose
	to explicitely have ``test-rcpt-dns-rbl -'' at some of the recipient
	domains you list at ``smtp-policy.mx'' file: 

	  #sample.domain.with.rbl
	  sample.domain.no.rbl    test-rcpt-dns-rbl -

3. smtp-policy.src boiler-plate

#| File:  $MAILVAR/db/smtp-policy.src
#|
#|  Policy based filter database boilerplate for smtpserver
#|  This file is compiled into actual database by command:
#|         $MAILBIN/policy-builder.sh
#|
#|  File syntax and semantics are explained towards the _end_ of this file.
#|
#|  Further documentation about related files, see file:
#|       doc/guides/smtp-policy
#|  See also comments in this file about various sub-options!

#|-----------
#|
#| Default handling boilerplates:
#|
#|   "We are not relaying between off-site hosts, except when ..."
#|
#| You MUST uncomment one of these default-defining pairs, or the blocking
#| of relay hijack will not work at all !
#|
#| -- 1st alternate: No MX target usage, no DNS existence verify
#|    Will accept for reception only those domains explicitely listed
#|    in  'smtp-policy.mx'  and  'localnames'  files.  Will not do
#|    verifications on validity/invalidity of source domains:  <foo@bar>
#
# _default_dot		relaycustomer - relaytarget -
# _default_ipaddr	relaycustomer - relaytarget -
#
#| -- 2nd alternate: No MX target usage, DNS existence verify
#|    Like the 1st alternate, except will verify the sender (mail from:<..>)
#|    address for existence of the DNS MX and/or A/AAAA data -- e.g. validity.
#|    If RBL parameters are set below, will use them.
#
# _default_dot		relaycustomer - relaytarget - senderokwithdns + = _rbl1
# _default_ipaddr	relaycustomer - relaytarget - senderokwithdns + = _rbl0
#
#| -- 3rd alternate: MX relay trust, DNS existence verify
#|    For the people who are in deep s*...  That is, those who for some
#|    reason have given open permissions for people to use their server
#|    as MX backup for their clients, but don't know all domains valid
#|    to go thru...  Substitutes accurate data to user's whimsical DNS
#|    maintenance activities.  Vulnerable to unauthorized inbound MX
#|    service abuse.
#|    If RBL parameters are set below, will use them.

_default_dot		relaycustomer - acceptifmx - senderokwithdns + = _rbl1
_default_ipaddr		relaycustomer - acceptifmx - senderokwithdns + = _rbl0

#| -- 4th alternate: Sender & recipient DNS existence verify
#|    This is more of an example for the symmetry's sake, verifies that
#|    the source and destination domains are DNS resolvable, but does not
#|    block relaying -- DANGER! DANGER! WILL ROBINSON! DANGER!
#
# _default_dot		senderokwithdns - acceptifdns -
# _default_ipaddr	senderokwithdns - acceptifdns -
#


#| -----------------------------------
#|  Now use above defined macroes at these default labels:
.		= _default_dot
[0.0.0.0]/0	= _default_ipaddr

#| -----------------------------------
#|
#| RBL type test rules:

#| First RBL variant: NONE OF THE RBL TESTS
_rbl0           # Nothing at early phase
_rbl1           # Nothing at late phase

#| Second RBL variant: Early block with RBL+DUL+RSS
#_rbl0          test-dns-rbl      +:dul.maps.vix.com:relays.mail-abuse.org
#_rbl1          # Nothing at late phase

#| Third RBL variant: Late block with RBL+DUL+RSS
#_rbl0          rcpt-dns-rbl      +:dul.maps.vix.com:relays.mail-abuse.org
#_rbl1          test-rcpt-dns-rbl +

#|  (The "+" at the DNS zone defines is treated as shorthand to
#|   "rbl.maps.vix.com")
#|
#|  The Third RBL variant means that all target domains can all by themselves
#|  choose if they use RBL to do source filtering.  The ``= _RBL1'' test
#|  *must* be added to all domain instances where the check is wanted.
#|  (Including the last-resort domain default of ".")
#|  (Or inverting: If some recipient domain is *not* wanting RBL-type tests,
#|   that domain shall have  ``test-rcpt-dns-rbl -'' attribute pair given for
#|   it at the input datasets -- consider  smtp-policy.mx  file!)
#|
#|-----------
#|
#| If your system has ``whoson'' server (see contrib/whoson-*.tgz),
#| you can activate it by adding  'trust-whoson +' attribute pair to
#| the wild-card IP address test:  [0.0.0.0]/0  of your choise.
#|
#|-----------
#|
#| If you want explicitely to run content-filter even for locally
#| accepted source IP addresses, you can activate it by adding
#| 'filtering +' attribute pair to  a)  the wild-card IP address test:
#|     [0.0.0.0]/0
#| of your choice above, and  b)  into  _full_rights  further below.
#|
#| This attribute pair is looked up only in early connect tests, never
#| afterwards.   If the attribute pair is not present, tests causing
#| internal  'always_accept'  flag to be set will disable the lookup
#| (effectively 'filtering -').
#|
#| With 'filtering +' added into  _full_rights,  entering explicite
#| 'filtering -'  for an address literal in  smtp-policy.relay*  file
#| will disable the content filtering for given address, while it
#| is activated for all others.
#|
#|-----------
#|
#| For outbound relaying control for fixed IP address networks, see
#| comments in file:  smtp-policy.relay
#|
#|-----------
#|
#| Generally we refuse SMTP connections from host in private address space
#| and refuse mails to or from <user@[nn.nn.nn.nn]> if nn.nn.nn.nn is a
#| private IP address...
#|
_private_address    message "We reject your network" rejectnet + message "We don't accept email from this source address" rejectsource + relaycustomer - relaytarget -
#[172.16.0.0]/12         = _private_address
#[192.168.0.0]/16        = _private_address
#[10.0.0.0]/8            = _private_address
#|
#| ...but hosts in the address range 192.168.16.0-192.168.17.255 may be
#| our SMTP clients.
#|
#[192.168.16.0]/23	rejectnet - = _private_address

#| Hosts of our organization can do anything...
#|
_our_network	= _full_rights

#|    Boilerplate macroes for various things.
#|    If RBL parameters are set above, will use them.

_full_rights	rejectnet - relaycustnet + relaytarget +               = _rbl1
_localnames	rejectnet - relaycustnet - localdomain + relaytarget + = _rbl1
_relaytarget	relaytarget +                                          = _rbl1

#|
#| Thanks, no bulk mails! Drop them when used as sources, also reject
#| when asked to send for them.
#|
_bulk_mail	message "Your address is not liked source for email" rejectsource + message "Your IP address is not liked source for email" rejectnet + message "This is not accepted relay target" relaytarget -
#|
#| The actual list of domains, and perhaps user addresses should
#| be gotten from some active Anti-SPAM database
#|
#nobody.com		= _bulk_mail
#.nobody.com		= _bulk_mail
#nodomain.com		= _bulk_mail
#.nodomain.com		= _bulk_mail
#|
#| Some source users we reject always: (frequent spammers..)
#| (see comment above about Anti-SPAM databases)
#| (Do note that these are SMTP ENVELOPE items, not RFC-822 items!)
#|
#friend@		= _bulk_mail
#friends@		= _bulk_mail

#----------------------------------
#| Syntax:
#|
#| key	[attribute value]... [= _tag]
#|
#|  The db compiler  does not accept completely empty value-set input,
#|  therefore there are comments in all  _ZZZ  entries if nothing else!
#| 
#| Where:
#|
#| 'key' is 
#|   - a domain name optionally preceded by a dot (.)
#|   - "user@" / "user@domain" names.
#|   - an IP address expression in canonical [nn.nn.nn.nn]/prefix form.
#|	Unspecified bits must be 0. (Network IPv6 addresses containing
#|       IPv4-mapped addresses are translated into plain IPv4.)
#|   - any arbitrary word referred as '_tag' at the right side
#|     '_tag' may be any key of this database
#|
#| 'attribute' and 'value' are tokens. They are used by policytest() to
#|     make decisions.  Attribute names, and understood value tokens are:
#|
#|	'='		'_any_token_with_starting_underscore' (aliasing)
#|				Recursion up to 3 levels is supported
#|	'rejectnet'	{ '+', '-' }
#|	'freezenet'	{ '+', '-' }
#|	'rejectsource'	{ '+', '-' }
#|	'freezesource'	{ '+', '-' }
#|	'relaycustomer'	{ '+', '-' }
#|	'relaycustnet'	{ '+', '-' }
#|	'relaytarget'	{ '+', '-' }
#|	'freeze'	{ '+', '-' }
#|	'senderokwithdns' { '+', '-' }
#|	'acceptifmx'	{ '+', '-' }
#|	'acceptifdns'	{ '+', '-' }
#|	'sendernorelay' { '+', '-' }
#|	'test-dns-rbl'	{ '+', '-', "suffix.one:suffix.two" }
#|	  Sample suffixes: rbl.maps.vix.com  relays.mail-abuse.org
#|			   dul.maps.vix.com
#|			   ok.orbs.org:relays.orbs.org  <-- that is a PAIR!
#|	'rcpt-dns-rbl'	{ '+', '-', "suffix.one:suffix.two" }
#|	'test-rcpt-dns-rbl' { '+', '-', "suffix.one:suffix.two" }
#|	'message'	"quoted constant string message"
#|	'localdomain'	{ '+', '-' }
#|	'maxinsize'	nnn
#|	'maxoutsize'	nnn
#|	'fulltrustnet'	{ '+', '-' }
#|	'trustrecipients' { '+', '-' }
#|	'trust-whoson'	{ '+', '-' }
#|	'filtering'	{ '+', '-' }
#|
#| Semantics:
#|
#| The policytest() functions called by smtpserver to check the client host,
#| the sender's and recipients' addresses.  policytest() looks for name, and
#| address of client host as well as full and partial user address, and domain
#| part of sender and recipient addresses in this database.  The retrieved
#| attributes are used to make decissions on acepting or rejecting
#| the incoming mail.
#|
#| If looking for 'foo.bar.edu' and exact match failed, the database looks
#| keys in sequence:  '.foo.bar.edu', '.bar.edu', '.edu', and '.'.
#|
#| The order of entries in this file is indifferent.
#|
#| When searching an IP address the entry with the most common (leftside) bits
#| is returned. So you can have a [0.0.0.0]/0 entry what specifies the default
#| addributes for all unlisted IP addresses. (Both IPv4 and IPv6)
#|
#| '=' is a special attribute.
#| The notation '= _tag' means "See also at '_tag'". If server() doesn't
#| find the requested attribute of the object, it will replace object name
#| with '_tag' and restarts search.
#| 

#| Here is an example configuration, assumed the following decision
#| chains of smtpserver/policytest.c routines:
#|
#| Connection establishment:  (IP address tested)
#|
#|  if (IP address of SMTP client has 'REJECTNET +' attribute) then
#|   any further conversation refused
#|   [state->always_reject = 1; return REJECT;]
#|  if (IP address of SMTP client has 'FREEZENET +' attribute) then
#|   we present happy face, but always put the messages into a freezer..
#|   [state->always_freeze = 1; return FREEZE;]
#|  if (IP address of SMTP client has 'FILTERING' attribute) then
#|   set  state->content_filter  1/0 depending on '+'/'-' value
#|   If this attribute doesn't exist, set: state->content_filter = -1
#|   This will latter interact with  state->always_accept  variable
#|   in the content-filter interface...
#|  if (IP address of SMTP client has 'RELAYCUSTNET +' attribute) then
#|   sender accepted, recipients not checked
#|   [state->always_accept = 1; return ACCEPT;]
#|  if (IP address of SMTP client has 'TEST-DNS-RBL +' attribute) then
#|   we use RealtimeBlockingList DNS database.  If we get match from
#|   there, we do: [state->always_reject = 1; return REJECT;]
#|  if (IP address of SMTP client has "RCPT-DNS-RBL" attribute then
#|   save RBL lookup result for processing at "RCPTO TO:" phase
#|   [state->rbl_msg = <RBL_LOOKUP_RESULT>;]
#|  else
#|   return ACCEPT
#|
#| Connection extablishment; connection source DOMAIN test
#| (This is done on the reverser information of the IP address
#|  of the session source.)
#|
#|  if (state->always_reject == 1) return REJECT;
#|  if (state->always_freeze == 1) return FREEZE;
#|  if (state->always_accept == 1) return ACCEPT;
#|
#|  if (source domain of address of SMTP client has 'REJECTNET +' attribute) then
#|   any further conversation refused
#|   [state->always_reject = 1; return REJECT;]
#|  if (source domain of of SMTP client has 'FREEZENET +' attribute) then
#|   we present happy face, but always put the messages into a freezer..
#|   [state->always_freeze = 1; return FREEZE;]
#|  if (source domain of SMTP client has 'RCPT-DNS-RBL "_Message' like attributes
#|   then save it for rejection at rcpt to: phase
#|   [state->rbl_msg = values[P_A_RcptDnsRBL] + 1;]
#|  else
#|   return ACCEPT
#|
#| HELO/EHLO parameter string:
#|
#|  if (state->always_reject == 1) return REJECT;
#|  if (state->always_freeze == 1) return FREEZE;
#|  if (state->always_accept == 1) return ACCEPT;
#|
#|  if (HELO-name of SMTP client has 'REJECTNET +' attribute) then
#|   any further conversation refused
#|   [state->always_reject = 1; return REJECT;]
#|  if (HELO-name of SMTP client has 'FREEZENET +' attribute) then
#|   we present happy face, but always put the messages into a freezer..
#|   [state->always_freeze = 1; return FREEZE;]
#|  default: return ACCEPT
#|
#| MAIL FROM address:
#|
#|  set state->rcpt_nocheck  = 0;
#|  set state->sender_reject = 0;
#|  set state->sender_freeze = 0;
#|
#|  if (state->always_reject == 1) return REJECT;
#|  if (state->always_freeze == 1) return FREEZE;
#|  if (state->always_accept == 1) return ACCEPT;
#|
#|  if (sender's address has 'REJECTSOURCE +' attribute) then
#|   sender rejected, any further conversation refused
#|   [state->always_reject = 1; return REJECT;]
#|  if (sender's address has 'FREEZESOURCE +' attribute) then
#|   we accept with the happy face, but place it into a freezer
#|   [state->always_freeze = 1; return FREEZE;]
#|  when (sender's address is not in policy-db, continue with sender's domain)
#|
#|  if (sender's domain is not in policy-db) then
#|    return ACCEPT
#|
#|  if (sender's domain has 'REJECTSOURCE +' attribute) then
#|   sender rejected, any further conversation refused
#|   [state->sender_reject = 1; return REJECT;]
#|  if (sender's domain has 'FREEZESOURCE +' attribute) then
#|   we accept with the happy face, but place it into a freezer
#|   [state->sender_freeze = 1; return FREEZE;]
#|  if (sender's domain has 'RELAYCUSTOMER +' attribute) then
#|   DANGER ! DANGER !
#|   We will accept all destination addresses for this MAIL FROM,
#|   except those that are explicitely blocked, of course..
#|   [state->rcpt_nocheck = 1; return ACCEPT;]
#|  if (sender's domain has 'SENDEROKWITHDNS +' attribute) then
#|    verify that is DNS data for the target domain.  If yes, return ACCEPT;
#|    if not, return SOFTREJECT
#|  if (sender's domain has 'SENDEROKWITHDNS -' attribute) then
#|    verify that is DNS data for the target domain.  If yes, return ACCEPT;
#|    if not, return REJECT
#|  else
#|    return ACCEPT
#|
#| RCPT TO address:
#|
#|  if (state->always_reject == 1) return REJECT;
#|  if (state->sender_reject == 1) return REJECT;
#|  if (state->always_freeze == 1) return FREEZE;
#|  if (state->sender_freeze == 1) return FREEZE;
#|  if (state->always_accept == 1) return ACCEPT;
#|
#|  if (recipient address has 'RELAYTARGET +' attribute) then
#|    return ACCEPT
#|  if (recipient address has 'RELAYTARGET -' attribute) then
#|    return REJECT
#|  if (recipient address has 'FREEZE +' attribute) then
#|    we accept with the happy face, but place it into a freezer
#|    [status->sender_freeze = 1; return FREEZE;]
#|  if (recipient address has 'TEST-RCPT-DNS-RBL +' attribute) then
#|    return REJECT if have state->rblmsg
#|
#|  if (recipient's domain has 'RELAYTARGET +' attribute) then
#|    return ACCEPT
#|  if (recipient's domain has 'RELAYTARGET -' attribute) then
#|    return REJECT
#|  if (recipient's domain has 'FREEZE +' attribute) then
#|    we accept with the happy face, but place it into a freezer
#|    [status->sender_freeze = 1; return FREEZE;]
#|
#|  if (recipient domain has 'TEST-RCPT-DNS-RBL +' attribute) then
#|    return REJECT if have state->rblmsg
#|
#|
#|  If (state->rcpt_nocheck  == 1) return ACCEPT;
#|
#|  If (recipient's domain has 'ACCEPTIFMX +' attribute) then
#|    Verify that we are MX for the target domain.  If yes, return ACCEPT;
#|    If not, return SOFTREJECT
#|  If (recipient's domain has 'ACCEPTIFMX -' attribute) then
#|    Verify that we are MX for the target domain.  If yes, return ACCEPT;
#|    If not, return REJECT
#|  If (recipient's domain has 'ACCEPTIFDNS +' attribute) then
#|    Verify that we are MX for the target domain.  If yes, return ACCEPT;
#|    If not, return SOFTREJECT
#|  If (recipient's domain has 'ACCEPTIFDNS -' attribute) then
#|    Verify that we are MX for the target domain.  If yes, return ACCEPT;
#|    If not, return REJECT
#|  Else
#|    return ACCEPT
#| 
#| ------
#|
