1/*
2 * Copyright (c) 1998-2001, 2003, 2006, 2007 Proofpoint, Inc. and its suppliers.
3 *	All rights reserved.
4 * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
5 * Copyright (c) 1988, 1993
6 *	The Regents of the University of California.  All rights reserved.
7 *
8 * By using this file, you agree to the terms and conditions set
9 * forth in the LICENSE file which can be found at the top level of
10 * the sendmail distribution.
11 *
12 */
13
14#include <sendmail.h>
15
16SM_RCSID("@(#)$Id: macro.c,v 8.108 2013-11-22 20:51:55 ca Exp $")
17
18#include <sm/sendmail.h>
19#if MAXMACROID != (BITMAPBITS - 1)
20	ERROR Read the comment in conf.h
21#endif /* MAXMACROID != (BITMAPBITS - 1) */
22
23static char	*MacroName[MAXMACROID + 1];	/* macro id to name table */
24
25/*
26**  Codes for long named macros.
27**  See also macname():
28	* if not ASCII printable, look up the name *
29	if (n <= 0x20 || n > 0x7f)
30**  First use 1 to NEXTMACROID_L, then use NEXTMACROID_H to MAXMACROID.
31*/
32
33#define NEXTMACROID_L 037
34#define NEXTMACROID_H 0240
35
36#if _FFR_MORE_MACROS
37/* table for next id in non-printable ASCII range: disallow some value */
38static int NextMIdTable[] =
39{
40	/*  0  nul */	 1,
41	/*  1  soh */	 2,
42	/*  2  stx */	 3,
43	/*  3  etx */	 4,
44	/*  4  eot */	 5,
45	/*  5  enq */	 6,
46	/*  6  ack */	 7,
47	/*  7  bel */	 8,
48	/*  8  bs  */	14,
49	/*  9  ht  */	-1,
50	/* 10  nl  */	-1,
51	/* 11  vt  */	-1,
52	/* 12  np  */	-1,
53	/* 13  cr  */	-1,
54	/* 14  so  */	15,
55	/* 15  si  */	16,
56	/* 16  dle */	17,
57	/* 17  dc1 */	18,
58	/* 18  dc2 */	19,
59	/* 19  dc3 */	20,
60	/* 20  dc4 */	21,
61	/* 21  nak */	22,
62	/* 22  syn */	23,
63	/* 23  etb */	24,
64	/* 24  can */	25,
65	/* 25  em  */	26,
66	/* 26  sub */	27,
67	/* 27  esc */	28,
68	/* 28  fs  */	29,
69	/* 29  gs  */	30,
70	/* 30  rs  */	31,
71	/* 31  us  */	32,
72	/* 32  sp  */	-1,
73};
74
75#define NEXTMACROID(mid)	(		\
76	(mid < NEXTMACROID_L) ? (NextMIdTable[mid]) :	\
77	((mid < NEXTMACROID_H) ? NEXTMACROID_H : (mid + 1)))
78
79int		NextMacroId = 1;	/* codes for long named macros */
80/* see sendmail.h: Special characters in rewriting rules. */
81#else /* _FFR_MORE_MACROS */
82int		NextMacroId = 0240;	/* codes for long named macros */
83#define NEXTMACROID(mid)	((mid) + 1)
84#endif /* _FFR_MORE_MACROS */
85
86
87/*
88**  INITMACROS -- initialize the macro system
89**
90**	This just involves defining some macros that are actually
91**	used internally as metasymbols to be themselves.
92**
93**	Parameters:
94**		none.
95**
96**	Returns:
97**		none.
98**
99**	Side Effects:
100**		initializes several macros to be themselves.
101*/
102
103struct metamac	MetaMacros[] =
104{
105	/* LHS pattern matching characters */
106	{ '*', MATCHZANY },	{ '+', MATCHANY },	{ '-', MATCHONE },
107	{ '=', MATCHCLASS },	{ '~', MATCHNCLASS },
108
109	/* these are RHS metasymbols */
110	{ '#', CANONNET },	{ '@', CANONHOST },	{ ':', CANONUSER },
111	{ '>', CALLSUBR },
112
113	/* the conditional operations */
114	{ '?', CONDIF },	{ '|', CONDELSE },	{ '.', CONDFI },
115
116	/* the hostname lookup characters */
117	{ '[', HOSTBEGIN },	{ ']', HOSTEND },
118	{ '(', LOOKUPBEGIN },	{ ')', LOOKUPEND },
119
120	/* miscellaneous control characters */
121	{ '&', MACRODEXPAND },
122
123	{ '\0', '\0' }
124};
125
126#define MACBINDING(name, mid) \
127		stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \
128		MacroName[mid] = name;
129
130void
131initmacros(e)
132	ENVELOPE *e;
133{
134	struct metamac *m;
135	int c;
136	char buf[5];
137
138	for (m = MetaMacros; m->metaname != '\0'; m++)
139	{
140		buf[0] = m->metaval;
141		buf[1] = '\0';
142		macdefine(&e->e_macro, A_TEMP, m->metaname, buf);
143	}
144	buf[0] = MATCHREPL;
145	buf[2] = '\0';
146	for (c = '0'; c <= '9'; c++)
147	{
148		buf[1] = c;
149		macdefine(&e->e_macro, A_TEMP, c, buf);
150	}
151
152	/* set defaults for some macros sendmail will use later */
153	macdefine(&e->e_macro, A_PERM, 'n', "MAILER-DAEMON");
154
155	/* set up external names for some internal macros */
156	MACBINDING("opMode", MID_OPMODE);
157	/*XXX should probably add equivalents for all short macros here XXX*/
158}
159
160/*
161**  EXPAND/DOEXPAND -- macro expand a string using $x escapes.
162**
163**	After expansion, the expansion will be in external form (that is,
164**	there will be no sendmail metacharacters and METAQUOTEs will have
165**	been stripped out).
166**
167**	Parameters:
168**		s -- the string to expand.
169**		buf -- the place to put the expansion.
170**		bufsize -- the size of the buffer.
171**		explevel -- the depth of expansion (doexpand only)
172**		e -- envelope in which to work.
173**
174**	Returns:
175**		none.
176**
177**	Side Effects:
178**		none.
179*/
180
181static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *));
182
183static void
184doexpand(s, buf, bufsize, explevel, e)
185	char *s;
186	char *buf;
187	size_t bufsize;
188	int explevel;
189	ENVELOPE *e;
190{
191	char *xp;
192	char *q;
193	bool skipping;		/* set if conditionally skipping output */
194	bool recurse;		/* set if recursion required */
195	size_t i;
196	int skiplev;		/* skipping nesting level */
197	int iflev;		/* if nesting level */
198	bool quotenext;		/* quote the following character */
199	char xbuf[MACBUFSIZE];
200
201	if (tTd(35, 24))
202	{
203		sm_dprintf("expand(");
204		xputs(sm_debug_file(), s);
205		sm_dprintf(")\n");
206	}
207
208	recurse = false;
209	skipping = false;
210	skiplev = 0;
211	iflev = 0;
212	quotenext = false;
213	if (s == NULL)
214		s = "";
215	for (xp = xbuf; *s != '\0'; s++)
216	{
217		int c;
218
219		/*
220		**  Check for non-ordinary (special?) character.
221		**	'q' will be the interpolated quantity.
222		*/
223
224		q = NULL;
225		c = *s & 0377;
226
227		if (quotenext)
228		{
229			quotenext = false;
230			goto simpleinterpolate;
231		}
232
233		switch (c)
234		{
235		  case CONDIF:		/* see if var set */
236			iflev++;
237			c = *++s & 0377;
238			if (skipping)
239				skiplev++;
240			else
241			{
242				char *mv;
243
244				mv = macvalue(c, e);
245				skipping = (mv == NULL || *mv == '\0');
246			}
247			continue;
248
249		  case CONDELSE:	/* change state of skipping */
250			if (iflev == 0)
251				break;	/* XXX: error */
252			if (skiplev == 0)
253				skipping = !skipping;
254			continue;
255
256		  case CONDFI:		/* stop skipping */
257			if (iflev == 0)
258				break;	/* XXX: error */
259			iflev--;
260			if (skiplev == 0)
261				skipping = false;
262			if (skipping)
263				skiplev--;
264			continue;
265
266		  case MACROEXPAND:	/* macro interpolation */
267			c = bitidx(*++s);
268			if (c != '\0')
269				q = macvalue(c, e);
270			else
271			{
272				s--;
273				q = NULL;
274			}
275			if (q == NULL)
276				continue;
277			break;
278
279		  case METAQUOTE:
280			/* next octet completely quoted */
281			quotenext = true;
282			break;
283		}
284
285		/*
286		**  Interpolate q or output one character
287		*/
288
289  simpleinterpolate:
290		if (skipping || xp >= &xbuf[sizeof(xbuf) - 1])
291			continue;
292		if (q == NULL)
293			*xp++ = c;
294		else
295		{
296			/* copy to end of q or max space remaining in buf */
297			bool hiderecurse = false;
298
299			while ((c = *q++) != '\0' &&
300				xp < &xbuf[sizeof(xbuf) - 1])
301			{
302				/* check for any sendmail metacharacters */
303				if (!hiderecurse && (c & 0340) == 0200)
304					recurse = true;
305				*xp++ = c;
306
307				/* give quoted characters a free ride */
308				hiderecurse = (c & 0377) == METAQUOTE;
309			}
310		}
311	}
312	*xp = '\0';
313
314	if (tTd(35, 28))
315	{
316		sm_dprintf("expand(%d) ==> ", explevel);
317		xputs(sm_debug_file(), xbuf);
318		sm_dprintf("\n");
319	}
320
321	/* recurse as appropriate */
322	if (recurse)
323	{
324		if (explevel < MaxMacroRecursion)
325		{
326			doexpand(xbuf, buf, bufsize, explevel + 1, e);
327			return;
328		}
329		syserr("expand: recursion too deep (%d max)",
330			MaxMacroRecursion);
331	}
332
333	/* copy results out */
334	if (explevel == 0)
335		(void) sm_strlcpy(buf, xbuf, bufsize);
336	else
337	{
338		/* leave in internal form */
339		i = xp - xbuf;
340		if (i >= bufsize)
341			i = bufsize - 1;
342		memmove(buf, xbuf, i);
343		buf[i] = '\0';
344	}
345
346	if (tTd(35, 24))
347	{
348		sm_dprintf("expand ==> ");
349		xputs(sm_debug_file(), buf);
350		sm_dprintf("\n");
351	}
352}
353
354void
355expand(s, buf, bufsize, e)
356	char *s;
357	char *buf;
358	size_t bufsize;
359	ENVELOPE *e;
360{
361	doexpand(s, buf, bufsize, 0, e);
362}
363
364/*
365**  MACDEFINE -- bind a macro name to a value
366**
367**	Set a macro to a value, with fancy storage management.
368**	macdefine will make a copy of the value, if required,
369**	and will ensure that the storage for the previous value
370**	is not leaked.
371**
372**	Parameters:
373**		mac -- Macro table.
374**		vclass -- storage class of 'value', ignored if value==NULL.
375**			A_HEAP	means that the value was allocated by
376**				malloc, and that macdefine owns the storage.
377**			A_TEMP	means that value points to temporary storage,
378**				and thus macdefine needs to make a copy.
379**			A_PERM	means that value points to storage that
380**				will remain allocated and unchanged for
381**				at least the lifetime of mac.  Use A_PERM if:
382**				-- value == NULL,
383**				-- value points to a string literal,
384**				-- value was allocated from mac->mac_rpool
385**				   or (in the case of an envelope macro)
386**				   from e->e_rpool,
387**				-- in the case of an envelope macro,
388**				   value is a string member of the envelope
389**				   such as e->e_sender.
390**		id -- Macro id.  This is a single character macro name
391**			such as 'g', or a value returned by macid().
392**		value -- Macro value: either NULL, or a string.
393*/
394
395void
396#if SM_HEAP_CHECK
397macdefine_tagged(mac, vclass, id, value, file, line, grp)
398#else /* SM_HEAP_CHECK */
399macdefine(mac, vclass, id, value)
400#endif /* SM_HEAP_CHECK */
401	MACROS_T *mac;
402	ARGCLASS_T vclass;
403	int id;
404	char *value;
405#if SM_HEAP_CHECK
406	char *file;
407	int line;
408	int grp;
409#endif /* SM_HEAP_CHECK */
410{
411	char *newvalue;
412
413	if (id < 0 || id > MAXMACROID)
414		return;
415
416	if (tTd(35, 9))
417	{
418		sm_dprintf("%sdefine(%s as ",
419			mac->mac_table[id] == NULL ? "" : "re", macname(id));
420		xputs(sm_debug_file(), value);
421		sm_dprintf(")\n");
422	}
423
424	if (mac->mac_rpool == NULL)
425	{
426		char *freeit = NULL;
427
428		if (mac->mac_table[id] != NULL &&
429		    bitnset(id, mac->mac_allocated))
430			freeit = mac->mac_table[id];
431
432		if (value == NULL || vclass == A_HEAP)
433		{
434			sm_heap_checkptr_tagged(value, file, line);
435			newvalue = value;
436			clrbitn(id, mac->mac_allocated);
437		}
438		else
439		{
440#if SM_HEAP_CHECK
441			newvalue = sm_strdup_tagged_x(value, file, line, 0);
442#else /* SM_HEAP_CHECK */
443			newvalue = sm_strdup_x(value);
444#endif /* SM_HEAP_CHECK */
445			setbitn(id, mac->mac_allocated);
446		}
447		mac->mac_table[id] = newvalue;
448		if (freeit != NULL)
449			sm_free(freeit);
450	}
451	else
452	{
453		if (value == NULL || vclass == A_PERM)
454			newvalue = value;
455		else
456			newvalue = sm_rpool_strdup_x(mac->mac_rpool, value);
457		mac->mac_table[id] = newvalue;
458		if (vclass == A_HEAP)
459			sm_free(value);
460	}
461
462#if _FFR_RESET_MACRO_GLOBALS
463	switch (id)
464	{
465	  case 'j':
466		PSTRSET(MyHostName, value);
467		break;
468	}
469#endif /* _FFR_RESET_MACRO_GLOBALS */
470}
471
472/*
473**  MACSET -- set a named macro to a value (low level)
474**
475**	No fancy storage management; the caller takes full responsibility.
476**	Often used with macget; see also macdefine.
477**
478**	Parameters:
479**		mac -- Macro table.
480**		i -- Macro name, specified as an integer offset.
481**		value -- Macro value: either NULL, or a string.
482*/
483
484void
485macset(mac, i, value)
486	MACROS_T *mac;
487	int i;
488	char *value;
489{
490	if (i < 0 || i > MAXMACROID)
491		return;
492
493	if (tTd(35, 9))
494	{
495		sm_dprintf("macset(%s as ", macname(i));
496		xputs(sm_debug_file(), value);
497		sm_dprintf(")\n");
498	}
499	mac->mac_table[i] = value;
500}
501
502/*
503**  MACVALUE -- return uninterpreted value of a macro.
504**
505**	Does fancy path searching.
506**	The low level counterpart is macget.
507**
508**	Parameters:
509**		n -- the name of the macro.
510**		e -- envelope in which to start looking for the macro.
511**
512**	Returns:
513**		The value of n.
514**
515**	Side Effects:
516**		none.
517*/
518
519char *
520macvalue(n, e)
521	int n;
522	ENVELOPE *e;
523{
524	n = bitidx(n);
525	if (e != NULL && e->e_mci != NULL)
526	{
527		char *p = e->e_mci->mci_macro.mac_table[n];
528
529		if (p != NULL)
530			return p;
531	}
532	while (e != NULL)
533	{
534		char *p = e->e_macro.mac_table[n];
535
536		if (p != NULL)
537			return p;
538		if (e == e->e_parent)
539			break;
540		e = e->e_parent;
541	}
542	return GlobalMacros.mac_table[n];
543}
544
545/*
546**  MACNAME -- return the name of a macro given its internal id
547**
548**	Parameter:
549**		n -- the id of the macro
550**
551**	Returns:
552**		The name of n.
553**
554**	Side Effects:
555**		none.
556**
557**	WARNING:
558**		Not thread-safe.
559*/
560
561char *
562macname(n)
563	int n;
564{
565	static char mbuf[2];
566
567	n = (int)(unsigned char)n;
568	if (n > MAXMACROID)
569		return "***OUT OF RANGE MACRO***";
570
571	/* if not ASCII printable, look up the name */
572	if (n <= 0x20 || n > 0x7f)
573	{
574		char *p = MacroName[n];
575
576		if (p != NULL)
577			return p;
578		return "***UNDEFINED MACRO***";
579	}
580
581	/* if in the ASCII graphic range, just return the id directly */
582	mbuf[0] = n;
583	mbuf[1] = '\0';
584	return mbuf;
585}
586
587/*
588**  MACID_PARSE -- return id of macro identified by its name
589**
590**	Parameters:
591**		p -- pointer to name string -- either a single
592**			character or {name}.
593**		ep -- filled in with the pointer to the byte
594**			after the name.
595**
596**	Returns:
597**		0 -- An error was detected.
598**		1..MAXMACROID -- The internal id code for this macro.
599**
600**	Side Effects:
601**		If this is a new macro name, a new id is allocated.
602**		On error, syserr is called.
603*/
604
605int
606macid_parse(p, ep)
607	char *p;
608	char **ep;
609{
610	int mid;
611	char *bp;
612	char mbuf[MAXMACNAMELEN + 1];
613
614	if (tTd(35, 14))
615	{
616		sm_dprintf("macid(");
617		xputs(sm_debug_file(), p);
618		sm_dprintf(") => ");
619	}
620
621	if (*p == '\0' || (p[0] == '{' && p[1] == '}'))
622	{
623		syserr("Name required for macro/class");
624		if (ep != NULL)
625			*ep = p;
626		if (tTd(35, 14))
627			sm_dprintf("NULL\n");
628		return 0;
629	}
630	if (*p != '{')
631	{
632		/* the macro is its own code */
633		if (ep != NULL)
634			*ep = p + 1;
635		if (tTd(35, 14))
636		{
637			char buf[2];
638
639			buf[0] = *p;
640			buf[1] = '\0';
641			xputs(sm_debug_file(), buf);
642			sm_dprintf("\n");
643		}
644		return bitidx(*p);
645	}
646	bp = mbuf;
647	while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1])
648	{
649		if (isascii(*p) && (isalnum(*p) || *p == '_'))
650			*bp++ = *p;
651		else
652			syserr("Invalid macro/class character %c", *p);
653	}
654	*bp = '\0';
655	mid = -1;
656	if (*p == '\0')
657	{
658		syserr("Unbalanced { on %s", mbuf);	/* missing } */
659	}
660	else if (*p != '}')
661	{
662		syserr("Macro/class name ({%s}) too long (%d chars max)",
663			mbuf, (int) (sizeof(mbuf) - 1));
664	}
665	else if (mbuf[1] == '\0' && mbuf[0] >= 0x20)
666	{
667		/* ${x} == $x */
668		mid = bitidx(mbuf[0]);
669		p++;
670	}
671	else
672	{
673		STAB *s;
674
675		s = stab(mbuf, ST_MACRO, ST_ENTER);
676		if (s->s_macro != 0)
677			mid = s->s_macro;
678		else
679		{
680			if (NextMacroId > MAXMACROID)
681			{
682				syserr("Macro/class {%s}: too many long names",
683					mbuf);
684				s->s_macro = -1;
685			}
686			else
687			{
688				MacroName[NextMacroId] = s->s_name;
689				s->s_macro = mid = NextMacroId;
690				NextMacroId = NEXTMACROID(NextMacroId);
691			}
692		}
693		p++;
694	}
695	if (ep != NULL)
696		*ep = p;
697	if (mid < 0 || mid > MAXMACROID)
698	{
699		syserr("Unable to assign macro/class ID (mid = 0x%x)", mid);
700		if (tTd(35, 14))
701			sm_dprintf("NULL\n");
702		return 0;
703	}
704	if (tTd(35, 14))
705		sm_dprintf("0x%x\n", mid);
706	return mid;
707}
708
709/*
710**  WORDINCLASS -- tell if a word is in a specific class
711**
712**	Parameters:
713**		str -- the name of the word to look up.
714**		cl -- the class name.
715**
716**	Returns:
717**		true if str can be found in cl.
718**		false otherwise.
719*/
720
721bool
722wordinclass(str, cl)
723	char *str;
724	int cl;
725{
726	STAB *s;
727
728	s = stab(str, ST_CLASS, ST_FIND);
729	return s != NULL && bitnset(bitidx(cl), s->s_class);
730}
731