xref: /titanic_53/usr/src/cmd/sendmail/libmilter/main.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  *  Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers.
3*7c478bd9Sstevel@tonic-gate  *	All rights reserved.
4*7c478bd9Sstevel@tonic-gate  *
5*7c478bd9Sstevel@tonic-gate  * By using this file, you agree to the terms and conditions set
6*7c478bd9Sstevel@tonic-gate  * forth in the LICENSE file which can be found at the top level of
7*7c478bd9Sstevel@tonic-gate  * the sendmail distribution.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  */
10*7c478bd9Sstevel@tonic-gate 
11*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
12*7c478bd9Sstevel@tonic-gate 
13*7c478bd9Sstevel@tonic-gate #include <sm/gen.h>
14*7c478bd9Sstevel@tonic-gate SM_RCSID("@(#)$Id: main.c,v 8.79 2003/10/20 22:25:09 ca Exp $")
15*7c478bd9Sstevel@tonic-gate 
16*7c478bd9Sstevel@tonic-gate #define _DEFINE	1
17*7c478bd9Sstevel@tonic-gate #include "libmilter.h"
18*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
19*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
20*7c478bd9Sstevel@tonic-gate 
21*7c478bd9Sstevel@tonic-gate 
22*7c478bd9Sstevel@tonic-gate static smfiDesc_ptr smfi = NULL;
23*7c478bd9Sstevel@tonic-gate 
24*7c478bd9Sstevel@tonic-gate /*
25*7c478bd9Sstevel@tonic-gate **  SMFI_REGISTER -- register a filter description
26*7c478bd9Sstevel@tonic-gate **
27*7c478bd9Sstevel@tonic-gate **	Parameters:
28*7c478bd9Sstevel@tonic-gate **		smfilter -- description of filter to register
29*7c478bd9Sstevel@tonic-gate **
30*7c478bd9Sstevel@tonic-gate **	Returns:
31*7c478bd9Sstevel@tonic-gate **		MI_SUCCESS/MI_FAILURE
32*7c478bd9Sstevel@tonic-gate */
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate int
35*7c478bd9Sstevel@tonic-gate smfi_register(smfilter)
36*7c478bd9Sstevel@tonic-gate 	smfiDesc_str smfilter;
37*7c478bd9Sstevel@tonic-gate {
38*7c478bd9Sstevel@tonic-gate 	size_t len;
39*7c478bd9Sstevel@tonic-gate 
40*7c478bd9Sstevel@tonic-gate 	if (smfi == NULL)
41*7c478bd9Sstevel@tonic-gate 	{
42*7c478bd9Sstevel@tonic-gate 		smfi = (smfiDesc_ptr) malloc(sizeof *smfi);
43*7c478bd9Sstevel@tonic-gate 		if (smfi == NULL)
44*7c478bd9Sstevel@tonic-gate 			return MI_FAILURE;
45*7c478bd9Sstevel@tonic-gate 	}
46*7c478bd9Sstevel@tonic-gate 	(void) memcpy(smfi, &smfilter, sizeof *smfi);
47*7c478bd9Sstevel@tonic-gate 	if (smfilter.xxfi_name == NULL)
48*7c478bd9Sstevel@tonic-gate 		smfilter.xxfi_name = "Unknown";
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate 	len = strlen(smfilter.xxfi_name) + 1;
51*7c478bd9Sstevel@tonic-gate 	smfi->xxfi_name = (char *) malloc(len);
52*7c478bd9Sstevel@tonic-gate 	if (smfi->xxfi_name == NULL)
53*7c478bd9Sstevel@tonic-gate 		return MI_FAILURE;
54*7c478bd9Sstevel@tonic-gate 	(void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len);
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate 	/* compare milter version with hard coded version */
57*7c478bd9Sstevel@tonic-gate 	if (smfi->xxfi_version != SMFI_VERSION)
58*7c478bd9Sstevel@tonic-gate 	{
59*7c478bd9Sstevel@tonic-gate 		/* hard failure for now! */
60*7c478bd9Sstevel@tonic-gate 		smi_log(SMI_LOG_ERR,
61*7c478bd9Sstevel@tonic-gate 			"%s: smfi_register: version mismatch application: %d != milter: %d",
62*7c478bd9Sstevel@tonic-gate 			smfi->xxfi_name, smfi->xxfi_version,
63*7c478bd9Sstevel@tonic-gate 			(int) SMFI_VERSION);
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate 		/* XXX how about smfi? */
66*7c478bd9Sstevel@tonic-gate 		free(smfi->xxfi_name);
67*7c478bd9Sstevel@tonic-gate 		return MI_FAILURE;
68*7c478bd9Sstevel@tonic-gate 	}
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate 	return MI_SUCCESS;
71*7c478bd9Sstevel@tonic-gate }
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate /*
74*7c478bd9Sstevel@tonic-gate **  SMFI_STOP -- stop milter
75*7c478bd9Sstevel@tonic-gate **
76*7c478bd9Sstevel@tonic-gate **	Parameters:
77*7c478bd9Sstevel@tonic-gate **		none.
78*7c478bd9Sstevel@tonic-gate **
79*7c478bd9Sstevel@tonic-gate **	Returns:
80*7c478bd9Sstevel@tonic-gate **		success.
81*7c478bd9Sstevel@tonic-gate */
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate int
84*7c478bd9Sstevel@tonic-gate smfi_stop()
85*7c478bd9Sstevel@tonic-gate {
86*7c478bd9Sstevel@tonic-gate 	mi_stop_milters(MILTER_STOP);
87*7c478bd9Sstevel@tonic-gate 	return MI_SUCCESS;
88*7c478bd9Sstevel@tonic-gate }
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate /*
91*7c478bd9Sstevel@tonic-gate **  Default values for some variables.
92*7c478bd9Sstevel@tonic-gate **	Most of these can be changed with the functions below.
93*7c478bd9Sstevel@tonic-gate */
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate static int dbg = 0;
96*7c478bd9Sstevel@tonic-gate static char *conn = NULL;
97*7c478bd9Sstevel@tonic-gate static int timeout = MI_TIMEOUT;
98*7c478bd9Sstevel@tonic-gate static int backlog = MI_SOMAXCONN;
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate /*
101*7c478bd9Sstevel@tonic-gate **  SMFI_OPENSOCKET -- try the socket setup to make sure we'll be
102*7c478bd9Sstevel@tonic-gate **		       able to start up
103*7c478bd9Sstevel@tonic-gate **
104*7c478bd9Sstevel@tonic-gate **	Parameters:
105*7c478bd9Sstevel@tonic-gate **		rmsocket -- if true, instructs libmilter to attempt
106*7c478bd9Sstevel@tonic-gate **			to remove the socket before creating it;
107*7c478bd9Sstevel@tonic-gate **			only applies for "local:" or "unix:" sockets
108*7c478bd9Sstevel@tonic-gate **
109*7c478bd9Sstevel@tonic-gate **	Return:
110*7c478bd9Sstevel@tonic-gate **		MI_SUCCESS/MI_FAILURE
111*7c478bd9Sstevel@tonic-gate */
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate int
114*7c478bd9Sstevel@tonic-gate smfi_opensocket(rmsocket)
115*7c478bd9Sstevel@tonic-gate 	bool rmsocket;
116*7c478bd9Sstevel@tonic-gate {
117*7c478bd9Sstevel@tonic-gate 	if (smfi == NULL || conn == NULL)
118*7c478bd9Sstevel@tonic-gate 		return MI_FAILURE;
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate 	return mi_opensocket(conn, backlog, dbg, rmsocket, smfi);
121*7c478bd9Sstevel@tonic-gate }
122*7c478bd9Sstevel@tonic-gate 
123*7c478bd9Sstevel@tonic-gate /*
124*7c478bd9Sstevel@tonic-gate **  SMFI_SETDBG -- set debug level.
125*7c478bd9Sstevel@tonic-gate **
126*7c478bd9Sstevel@tonic-gate **	Parameters:
127*7c478bd9Sstevel@tonic-gate **		odbg -- new debug level.
128*7c478bd9Sstevel@tonic-gate **
129*7c478bd9Sstevel@tonic-gate **	Returns:
130*7c478bd9Sstevel@tonic-gate **		MI_SUCCESS
131*7c478bd9Sstevel@tonic-gate */
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate int
134*7c478bd9Sstevel@tonic-gate smfi_setdbg(odbg)
135*7c478bd9Sstevel@tonic-gate 	int odbg;
136*7c478bd9Sstevel@tonic-gate {
137*7c478bd9Sstevel@tonic-gate 	dbg = odbg;
138*7c478bd9Sstevel@tonic-gate 	return MI_SUCCESS;
139*7c478bd9Sstevel@tonic-gate }
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate /*
142*7c478bd9Sstevel@tonic-gate **  SMFI_SETTIMEOUT -- set timeout (for read/write).
143*7c478bd9Sstevel@tonic-gate **
144*7c478bd9Sstevel@tonic-gate **	Parameters:
145*7c478bd9Sstevel@tonic-gate **		otimeout -- new timeout.
146*7c478bd9Sstevel@tonic-gate **
147*7c478bd9Sstevel@tonic-gate **	Returns:
148*7c478bd9Sstevel@tonic-gate **		MI_SUCCESS
149*7c478bd9Sstevel@tonic-gate */
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate int
152*7c478bd9Sstevel@tonic-gate smfi_settimeout(otimeout)
153*7c478bd9Sstevel@tonic-gate 	int otimeout;
154*7c478bd9Sstevel@tonic-gate {
155*7c478bd9Sstevel@tonic-gate 	timeout = otimeout;
156*7c478bd9Sstevel@tonic-gate 	return MI_SUCCESS;
157*7c478bd9Sstevel@tonic-gate }
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate /*
160*7c478bd9Sstevel@tonic-gate **  SMFI_SETCONN -- set connection information (socket description)
161*7c478bd9Sstevel@tonic-gate **
162*7c478bd9Sstevel@tonic-gate **	Parameters:
163*7c478bd9Sstevel@tonic-gate **		oconn -- new connection information.
164*7c478bd9Sstevel@tonic-gate **
165*7c478bd9Sstevel@tonic-gate **	Returns:
166*7c478bd9Sstevel@tonic-gate **		MI_SUCCESS/MI_FAILURE
167*7c478bd9Sstevel@tonic-gate */
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate int
170*7c478bd9Sstevel@tonic-gate smfi_setconn(oconn)
171*7c478bd9Sstevel@tonic-gate 	char *oconn;
172*7c478bd9Sstevel@tonic-gate {
173*7c478bd9Sstevel@tonic-gate 	size_t l;
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate 	if (oconn == NULL || *oconn == '\0')
176*7c478bd9Sstevel@tonic-gate 		return MI_FAILURE;
177*7c478bd9Sstevel@tonic-gate 	l = strlen(oconn) + 1;
178*7c478bd9Sstevel@tonic-gate 	if ((conn = (char *) malloc(l)) == NULL)
179*7c478bd9Sstevel@tonic-gate 		return MI_FAILURE;
180*7c478bd9Sstevel@tonic-gate 	if (sm_strlcpy(conn, oconn, l) >= l)
181*7c478bd9Sstevel@tonic-gate 		return MI_FAILURE;
182*7c478bd9Sstevel@tonic-gate 	return MI_SUCCESS;
183*7c478bd9Sstevel@tonic-gate }
184*7c478bd9Sstevel@tonic-gate 
185*7c478bd9Sstevel@tonic-gate /*
186*7c478bd9Sstevel@tonic-gate **  SMFI_SETBACKLOG -- set backlog
187*7c478bd9Sstevel@tonic-gate **
188*7c478bd9Sstevel@tonic-gate **	Parameters:
189*7c478bd9Sstevel@tonic-gate **		obacklog -- new backlog.
190*7c478bd9Sstevel@tonic-gate **
191*7c478bd9Sstevel@tonic-gate **	Returns:
192*7c478bd9Sstevel@tonic-gate **		MI_SUCCESS/MI_FAILURE
193*7c478bd9Sstevel@tonic-gate */
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate int
196*7c478bd9Sstevel@tonic-gate smfi_setbacklog(obacklog)
197*7c478bd9Sstevel@tonic-gate 	int obacklog;
198*7c478bd9Sstevel@tonic-gate {
199*7c478bd9Sstevel@tonic-gate 	if (obacklog <= 0)
200*7c478bd9Sstevel@tonic-gate 		return MI_FAILURE;
201*7c478bd9Sstevel@tonic-gate 	backlog = obacklog;
202*7c478bd9Sstevel@tonic-gate 	return MI_SUCCESS;
203*7c478bd9Sstevel@tonic-gate }
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate /*
207*7c478bd9Sstevel@tonic-gate **  SMFI_MAIN -- setup milter connnection and start listener.
208*7c478bd9Sstevel@tonic-gate **
209*7c478bd9Sstevel@tonic-gate **	Parameters:
210*7c478bd9Sstevel@tonic-gate **		none.
211*7c478bd9Sstevel@tonic-gate **
212*7c478bd9Sstevel@tonic-gate **	Returns:
213*7c478bd9Sstevel@tonic-gate **		MI_SUCCESS/MI_FAILURE
214*7c478bd9Sstevel@tonic-gate */
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate int
217*7c478bd9Sstevel@tonic-gate smfi_main()
218*7c478bd9Sstevel@tonic-gate {
219*7c478bd9Sstevel@tonic-gate 	int r;
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate 	(void) signal(SIGPIPE, SIG_IGN);
222*7c478bd9Sstevel@tonic-gate 	if (conn == NULL)
223*7c478bd9Sstevel@tonic-gate 	{
224*7c478bd9Sstevel@tonic-gate 		smi_log(SMI_LOG_FATAL, "%s: missing connection information",
225*7c478bd9Sstevel@tonic-gate 			smfi->xxfi_name);
226*7c478bd9Sstevel@tonic-gate 		return MI_FAILURE;
227*7c478bd9Sstevel@tonic-gate 	}
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate 	(void) atexit(mi_clean_signals);
230*7c478bd9Sstevel@tonic-gate 	if (mi_control_startup(smfi->xxfi_name) != MI_SUCCESS)
231*7c478bd9Sstevel@tonic-gate 	{
232*7c478bd9Sstevel@tonic-gate 		smi_log(SMI_LOG_FATAL,
233*7c478bd9Sstevel@tonic-gate 			"%s: Couldn't start signal thread",
234*7c478bd9Sstevel@tonic-gate 			smfi->xxfi_name);
235*7c478bd9Sstevel@tonic-gate 		return MI_FAILURE;
236*7c478bd9Sstevel@tonic-gate 	}
237*7c478bd9Sstevel@tonic-gate 	r = MI_SUCCESS;
238*7c478bd9Sstevel@tonic-gate 
239*7c478bd9Sstevel@tonic-gate 	/* Startup the listener */
240*7c478bd9Sstevel@tonic-gate 	if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)
241*7c478bd9Sstevel@tonic-gate 		r = MI_FAILURE;
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 	return r;
244*7c478bd9Sstevel@tonic-gate }
245*7c478bd9Sstevel@tonic-gate 
246