xref: /illumos-gate/usr/src/cmd/sendmail/lib/smtp-sendmail (revision d29f5a711240f866521445b1656d114da090335e)
1#!/sbin/sh
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23# Use is subject to license terms.
24#
25# ident	"%Z%%M%	%I%	%E% SMI"
26
27. /lib/svc/share/smf_include.sh
28
29ERRMSG1='WARNING: /var/mail is NFS-mounted without setting actimeo=0,'
30ERRMSG2='this can cause mailbox locking and access problems.'
31SERVER_PID_FILE="/var/run/sendmail.pid"
32CLIENT_PID_FILE="/var/spool/clientmqueue/sm-client.pid"
33DEFAULT_FILE="/etc/default/sendmail"
34ALIASES_FILE="/etc/mail/aliases"
35SENDMAIL_CF="/etc/mail/sendmail.cf"
36SUBMIT_CF="/etc/mail/submit.cf"
37SENDMAIL="/usr/lib/sendmail"
38PATH="/usr/bin:/usr/sbin:/usr/ccs/bin"
39export PATH
40
41check_queue_interval_syntax()
42{
43	default="15m"
44	if [ $# -lt 1 ]; then
45		answer=$default
46		return
47	fi
48	if echo $1 | egrep '^([0-9]*[1-9][0-9]*[smhdw])+$' >/dev/null 2>&1; then
49		answer=$1
50	else
51		answer=$default
52	fi
53}
54
55check_and_kill()
56{
57	PID=`head -1 $1`
58	kill -0 $PID > /dev/null 2>&1
59	[ $? -eq 0 ] && kill $PID
60}
61
62exist_or_exit()
63{
64	if [ ! -f $1 ]; then
65		echo "$1 does not exist"
66		exit $SMF_EXIT_ERR_CONFIG
67	fi
68}
69
70turn_m4_crank()
71{
72	# expected to be called with two arguments: .cf path & path to m4 file
73	[ $# -lt 2 ] && return
74	cf_path=$1
75	m4_path=$2
76	case "$m4_path" in
77	/*)	;;	# absolute path
78	*)	return;;
79	esac
80	if [ "$m4_path" = "_DONT_TOUCH_THIS" ]; then
81		if [ -f "${cf_path}.old" ]; then
82			mv "$cf_path" "${cf_path}.new"
83			[ $? -ne 0 ] && exit $SMF_EXIT_ERR_CONFIG
84			mv "${cf_path}.old" "$cf_path"
85			[ $? -ne 0 ] && exit $SMF_EXIT_ERR_CONFIG
86		fi
87		#
88		# If ${cf_path}.old does not exist, assume it was taken care
89		# of on a previous run.
90		#
91	else
92		exist_or_exit "$m4_path"
93		cd `dirname "$m4_path"`
94		base=`basename "$m4_path"`
95		name=`basename "$m4_path" .mc`
96		info=`svcprop -p config/include_info $SMF_FMRI 2>/dev/null`
97		if [ "$info" = "true" ]; then
98			m4flags=""
99		else
100			m4flags="-DSUN_HIDE_INTERNAL_DETAILS"
101		fi
102		m4 $m4flags /etc/mail/cf/m4/cf.m4 "$base" > "${name}.cf"
103		[ $? -ne 0 ] && exit $SMF_EXIT_ERR_CONFIG
104		cmp -s "${name}.cf" "$cf_path" || (
105			cp "${name}.cf" "${cf_path}.tmp" &&
106			chown root:bin "${cf_path}.tmp" &&
107			chmod 444 "${cf_path}.tmp" &&
108			mv "${cf_path}.tmp" "$cf_path"
109		)
110		[ $? -ne 0 ] && exit $SMF_EXIT_ERR_CONFIG
111	fi
112}
113
114case "$1" in
115'refresh')
116        [ -f $SERVER_PID_FILE ] && kill -1 `head -1 $SERVER_PID_FILE`
117        [ -f $CLIENT_PID_FILE ] && kill -1 `head -1 $CLIENT_PID_FILE`
118        ;;
119
120'start')
121	exist_or_exit $SENDMAIL
122	if [ ! -d /var/spool/mqueue ]; then
123		/usr/bin/mkdir -m 0750 /var/spool/mqueue
124		/usr/bin/chown root:bin /var/spool/mqueue
125	fi
126	if [ ! -f $ALIASES_FILE.db ] && [ ! -f $ALIASES_FILE.dir ] \
127	    && [ ! -f $ALIASES_FILE.pag ]; then
128		/usr/sbin/newaliases
129	fi
130	MODE="-bd"
131	[ -f $DEFAULT_FILE ] && . $DEFAULT_FILE
132	#
133	# * MODE should be "-bd" or null (MODE= or MODE="") or
134	#   left alone.  Anything else and you're on your own.
135	# * QUEUEOPTION should be "p" or null (as above).
136	# * [CLIENT]QUEUEINTERVAL should be set to some legal value;
137	#   sanity checks are done below.
138	# * [CLIENT]OPTIONS are catch-alls; set with care.
139	#
140	if [ -n "$QUEUEOPTION" -a "$QUEUEOPTION" != "p" ]; then
141		QUEUEOPTION=""
142	fi
143	if [ -z "$QUEUEOPTION" -o -n "$QUEUEINTERVAL" ]; then
144		check_queue_interval_syntax $QUEUEINTERVAL
145		QUEUEINTERVAL=$answer
146	fi
147	check_queue_interval_syntax $CLIENTQUEUEINTERVAL
148	CLIENTQUEUEINTERVAL=$answer
149
150	local=`/usr/bin/svcprop -p config/local_only $SMF_FMRI 2>/dev/null`
151	if [ $? -eq 0 -a "$local" = "true" ]; then
152		MODE="-bl"
153	fi
154	sendmail_path=`svcprop -p config/path_to_sendmail_mc $SMF_FMRI \
155	    2>/dev/null`
156	if [ $? -eq 0 -a -n "$sendmail_path" ]; then
157		turn_m4_crank $SENDMAIL_CF $sendmail_path
158	fi
159	exist_or_exit $SENDMAIL_CF
160	submit_path=`svcprop -p config/path_to_submit_mc $SMF_FMRI 2>/dev/null`
161	if [ $? -eq 0 -a -n "$submit_path" ]; then
162		turn_m4_crank $SUBMIT_CF $submit_path
163	fi
164	exist_or_exit $SUBMIT_CF
165
166	$SENDMAIL $MODE -q$QUEUEOPTION$QUEUEINTERVAL $OPTIONS &
167	$SENDMAIL -Ac -q$CLIENTQUEUEINTERVAL $CLIENTOPTIONS &
168
169	#
170	# ETRN_HOSTS should be of the form
171	# "s1:c1.1,c1.2        s2:c2.1 s3:c3.1,c3.2,c3.3"
172	# i.e., white-space separated groups of server:client where
173	# client can be one or more comma-separated names; N.B. that
174	# the :client part is optional; see etrn(1M) for details.
175	# server is the name of the server to prod; a mail queue run
176	# is requested for each client name.  This is comparable to
177	# running "/usr/lib/sendmail -qRclient" on the host server.
178	#
179	# See RFC 1985 for more information.
180	#
181	for i in $ETRN_HOSTS; do
182		SERVER=`echo $i | /usr/bin/sed -e 's/:.*$//'`
183		CLIENTS=`echo $i | /usr/bin/sed -n -e 's/,/ /g' \
184		    -e '/:/s/^.*://p'`
185		/usr/sbin/etrn -b $SERVER $CLIENTS >/dev/null 2>&1 &
186	done
187
188	if /usr/bin/nawk 'BEGIN{s = 1}
189	    $2 == "/var/mail" && $3 == "nfs" && $4 !~ /actimeo=0/ &&
190	    $4 !~ /noac/{s = 0} END{exit s}' /etc/mnttab; then
191
192		/usr/bin/logger -p mail.crit "$ERRMSG1"
193		/usr/bin/logger -p mail.crit "$ERRMSG2"
194	fi
195	;;
196
197'stop')
198	[ -f $SERVER_PID_FILE ] && check_and_kill $SERVER_PID_FILE
199	if [ -f $CLIENT_PID_FILE ]; then
200		check_and_kill $CLIENT_PID_FILE
201		rm -f $CLIENT_PID_FILE
202	fi
203	# Need to kill the entire service contract to kill all sendmail related
204	# processes
205	smf_kill_contract $2 TERM 1 30
206	ret=$?
207	[ $ret -eq 1 ] && exit 1
208
209	# Since sendmail spawns user processes out of .forward files, it is
210	# possible that some of these are not responding to TERM.  If the
211	# contract did not empty after TERM, move on to KILL.
212	if [ $ret -eq 2 ] ; then
213		smf_kill_contract $2 KILL 1
214	fi
215	;;
216
217*)
218	echo "Usage: $0 { start | stop | refresh }"
219	exit 1
220	;;
221esac
222exit 0
223