xref: /freebsd/libexec/rc/rc.d/sendmail (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
1#!/bin/sh
2#
3#
4
5# PROVIDE: mail
6# REQUIRE: LOGIN FILESYSTEMS
7# KEYWORD: shutdown
8#
9# We make mail start late, so that things like .forward's are not processed
10# until the system is fully operational.
11
12# XXX - Get together with sendmail mantainer to figure out how to
13#	better handle SENDMAIL_ENABLE and 3rd party MTAs.
14#
15. /etc/rc.subr
16
17name="sendmail"
18desc="Electronic mail transport agent"
19rcvar="sendmail_enable"
20required_files="/etc/mail/${name}.cf"
21start_precmd="sendmail_precmd"
22
23: ${sendmail_svcj_options:="net_basic"}
24
25load_rc_config $name
26command=${sendmail_program:-/usr/sbin/${name}}
27pidfile=${sendmail_pidfile:-/var/run/${name}.pid}
28procname=${sendmail_procname:-/usr/sbin/${name}}
29
30CERTDIR=/etc/mail/certs
31
32case ${sendmail_enable} in
33[Nn][Oo][Nn][Ee])
34	sendmail_enable="NO"
35	sendmail_submit_enable="NO"
36	sendmail_outbound_enable="NO"
37	sendmail_msp_queue_enable="NO"
38	;;
39esac
40
41# If sendmail_enable=yes, don't need submit or outbound daemon
42if checkyesno sendmail_enable; then
43	sendmail_submit_enable="NO"
44	sendmail_outbound_enable="NO"
45	_sendmail_run=true
46fi
47
48# If sendmail_submit_enable=yes, don't need outbound daemon
49if checkyesno sendmail_submit_enable; then
50	name="sendmail_submit"
51	rcvar="sendmail_submit_enable"
52	sendmail_outbound_enable="NO"
53	_sendmail_run=true
54fi
55
56if checkyesno sendmail_outbound_enable; then
57	name="sendmail_outbound"
58	rcvar="sendmail_outbound_enable"
59	_sendmail_run=true
60fi
61
62if checkyesno sendmail_msp_queue_enable; then
63	_sendmail_msp_queue_run=true
64else
65	# Make sure run_rc_command is called at least once.
66	_sendmail_run=true
67fi
68
69sendmail_cert_create()
70{
71	cnname="${sendmail_cert_cn:-`hostname`}"
72	cnname="${cnname:-amnesiac}"
73
74	# based upon:
75	# http://www.sendmail.org/~ca/email/other/cagreg.html
76	CAdir=`mktemp -d` &&
77	certpass=`(date; ps ax ; hostname) | md5 -q`
78
79	# make certificate authority
80	( cd "$CAdir" &&
81	chmod 700 "$CAdir" &&
82	mkdir certs crl newcerts &&
83	echo "01" > serial &&
84	:> index.txt &&
85
86	cat <<-OPENSSL_CNF > openssl.cnf &&
87		RANDFILE	= $CAdir/.rnd
88		[ ca ]
89		default_ca	= CA_default
90		[ CA_default ]
91		dir		= .
92		certs		= \$dir/certs		# Where the issued certs are kept
93		crl_dir		= \$dir/crl		# Where the issued crl are kept
94		database	= \$dir/index.txt	# database index file.
95		new_certs_dir	= \$dir/newcerts	# default place for new certs.
96		certificate	= \$dir/cacert.pem 	# The CA certificate
97		serial		= \$dir/serial 		# The current serial number
98		crlnumber	= \$dir/crlnumber	# the current crl number
99		crl		= \$dir/crl.pem 	# The current CRL
100		private_key	= \$dir/cakey.pem
101		x509_extensions	= usr_cert		# The extensions to add to the cert
102		name_opt 	= ca_default		# Subject Name options
103		cert_opt 	= ca_default		# Certificate field options
104		default_days	= 365			# how long to certify for
105		default_crl_days= 30			# how long before next CRL
106		default_md	= default		# use public key default MD
107		preserve	= no			# keep passed DN ordering
108		policy		= policy_anything
109		[ policy_anything ]
110		countryName		= optional
111		stateOrProvinceName	= optional
112		localityName		= optional
113		organizationName	= optional
114		organizationalUnitName	= optional
115		commonName		= supplied
116		emailAddress		= optional
117		[ req ]
118		default_bits		= 2048
119		default_keyfile 	= privkey.pem
120		distinguished_name	= req_distinguished_name
121		attributes		= req_attributes
122		x509_extensions	= v3_ca	# The extensions to add to the self signed cert
123		string_mask = utf8only
124		prompt = no
125		[ req_distinguished_name ]
126		countryName			= XX
127		stateOrProvinceName		= Some-state
128		localityName			= Some-city
129		0.organizationName		= Some-org
130		CN				= $cnname
131		[ req_attributes ]
132		challengePassword		= foobar
133		unstructuredName		= An optional company name
134		[ usr_cert ]
135		basicConstraints=CA:FALSE
136		nsComment			= "OpenSSL Generated Certificate"
137		subjectKeyIdentifier=hash
138		authorityKeyIdentifier=keyid,issuer
139		[ v3_req ]
140		basicConstraints = CA:FALSE
141		keyUsage = nonRepudiation, digitalSignature, keyEncipherment
142		[ v3_ca ]
143		subjectKeyIdentifier=hash
144		authorityKeyIdentifier=keyid:always,issuer
145		basicConstraints = CA:true
146	OPENSSL_CNF
147
148	# though we use a password, the key is discarded and never used
149	openssl req -batch -passout pass:"$certpass" -new -x509 \
150	    -keyout cakey.pem -out cacert.pem -days 3650 \
151	    -config openssl.cnf -newkey rsa:2048 >/dev/null 2>&1 &&
152
153	# make new certificate
154	openssl req -batch -nodes -new -x509 -keyout newkey.pem \
155	    -out newreq.pem -days 365 -config openssl.cnf \
156	    -newkey rsa:2048 >/dev/null 2>&1 &&
157
158	# sign certificate
159	openssl x509 -x509toreq -in newreq.pem -signkey newkey.pem \
160	    -out tmp.pem >/dev/null 2>&1 &&
161	openssl ca -notext -config openssl.cnf \
162	    -out newcert.pem -keyfile cakey.pem -cert cacert.pem \
163	    -key "$certpass" -batch -infiles tmp.pem >/dev/null 2>&1 &&
164
165	mkdir -p "$CERTDIR" &&
166	chmod 0755 "$CERTDIR" &&
167	chmod 644 newcert.pem cacert.pem &&
168	chmod 600 newkey.pem &&
169	cp -p newcert.pem "$CERTDIR"/host.cert &&
170	cp -p cacert.pem "$CERTDIR"/cacert.pem &&
171	cp -p newkey.pem "$CERTDIR"/host.key &&
172	ln -s cacert.pem "$CERTDIR"/`openssl x509 -hash -noout \
173	    -in cacert.pem`.0)
174
175	retVal="$?"
176	rm -rf "$CAdir"
177
178	return "$retVal"
179}
180
181sendmail_precmd()
182{
183	# Die if there's pre-8.10 custom configuration file.  This check is
184	# mandatory for smooth upgrade.  See NetBSD PR 10100 for details.
185	#
186	if checkyesno ${rcvar} && [ -f "/etc/sendmail.cf" ]; then
187		if ! cmp -s "/etc/mail/sendmail.cf" "/etc/sendmail.cf"; then
188			warn \
189    "${name} was not started; you have multiple copies of sendmail.cf."
190			return 1
191		fi
192	fi
193
194	# check modifications on /etc/mail/aliases
195	if checkyesno sendmail_rebuild_aliases; then
196		if [ -f "/etc/mail/aliases.db" ]; then
197			if [ "/etc/mail/aliases" -nt "/etc/mail/aliases.db" ]; then
198				echo \
199	    	"${name}: /etc/mail/aliases newer than /etc/mail/aliases.db, regenerating"
200				/usr/bin/newaliases
201			fi
202		else
203			echo \
204	    	"${name}: /etc/mail/aliases.db not present, generating"
205				/usr/bin/newaliases
206		fi
207	fi
208
209	if checkyesno sendmail_cert_create && [ ! \( \
210	    -f "$CERTDIR/host.cert" -o -f "$CERTDIR/host.key" -o \
211	    -f "$CERTDIR/cacert.pem" \) ]; then
212		if ! openssl version >/dev/null 2>&1; then
213			warn "OpenSSL not available, but sendmail_cert_create is YES."
214		else
215			info Creating certificate for sendmail.
216			sendmail_cert_create
217		fi
218	fi
219
220	if [ ! -f /var/log/sendmail.st ]; then
221		/usr/bin/install -m 640 -o root -g wheel /dev/null /var/log/sendmail.st
222	fi
223}
224
225if ${_sendmail_run:-false}; then
226	run_rc_command "$1"
227fi
228_ret=$?
229
230if ${_sendmail_msp_queue_run:-false}; then
231	name="sendmail_msp_queue"
232	rcvar="sendmail_msp_queue_enable"
233	pidfile="${sendmail_msp_queue_pidfile:-/var/spool/clientmqueue/sm-client.pid}"
234	required_files="/etc/mail/submit.cf"
235	_rc_restart_done=false
236	run_rc_command "$1"
237	_ret=$(( _ret > $? ? _ret : $? ))
238fi
239
240(exit "$_ret")
241