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
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**  MACTABCLEAR -- clear entire macro table
366**
367**	Parameters:
368**		mac -- Macro table.
369**
370**	Returns:
371**		none.
372**
373**	Side Effects:
374**		clears entire mac structure including rpool pointer!
375*/
376
377void
378mactabclear(mac)
379	MACROS_T *mac;
380{
381	int i;
382
383	if (mac->mac_rpool == NULL)
384	{
385		for (i = 0; i < MAXMACROID; i++)
386			SM_FREE(mac->mac_table[i]);
387	}
388	memset((char *) mac, '\0', sizeof(*mac));
389}
390
391/*
392**  MACDEFINE -- bind a macro name to a value
393**
394**	Set a macro to a value, with fancy storage management.
395**	macdefine will make a copy of the value, if required,
396**	and will ensure that the storage for the previous value
397**	is not leaked.
398**
399**	Parameters:
400**		mac -- Macro table.
401**		vclass -- storage class of 'value', ignored if value==NULL.
402**			A_HEAP	means that the value was allocated by
403**				malloc, and that macdefine owns the storage.
404**			A_TEMP	means that value points to temporary storage,
405**				and thus macdefine needs to make a copy.
406**			A_PERM	means that value points to storage that
407**				will remain allocated and unchanged for
408**				at least the lifetime of mac.  Use A_PERM if:
409**				-- value == NULL,
410**				-- value points to a string literal,
411**				-- value was allocated from mac->mac_rpool
412**				   or (in the case of an envelope macro)
413**				   from e->e_rpool,
414**				-- in the case of an envelope macro,
415**				   value is a string member of the envelope
416**				   such as e->e_sender.
417**		id -- Macro id.  This is a single character macro name
418**			such as 'g', or a value returned by macid().
419**		value -- Macro value: either NULL, or a string.
420*/
421
422void
423#if SM_HEAP_CHECK
424macdefine_tagged(mac, vclass, id, value, file, line, grp)
425#else /* SM_HEAP_CHECK */
426macdefine(mac, vclass, id, value)
427#endif /* SM_HEAP_CHECK */
428	MACROS_T *mac;
429	ARGCLASS_T vclass;
430	int id;
431	char *value;
432#if SM_HEAP_CHECK
433	char *file;
434	int line;
435	int grp;
436#endif /* SM_HEAP_CHECK */
437{
438	char *newvalue;
439
440	if (id < 0 || id > MAXMACROID)
441		return;
442
443	if (tTd(35, 9))
444	{
445		sm_dprintf("%sdefine(%s as ",
446			mac->mac_table[id] == NULL ? "" : "re", macname(id));
447		xputs(sm_debug_file(), value);
448		sm_dprintf(")\n");
449	}
450
451	if (mac->mac_rpool == NULL)
452	{
453		char *freeit = NULL;
454
455		if (mac->mac_table[id] != NULL &&
456		    bitnset(id, mac->mac_allocated))
457			freeit = mac->mac_table[id];
458
459		if (value == NULL || vclass == A_HEAP)
460		{
461			sm_heap_checkptr_tagged(value, file, line);
462			newvalue = value;
463			clrbitn(id, mac->mac_allocated);
464		}
465		else
466		{
467#if SM_HEAP_CHECK
468			newvalue = sm_strdup_tagged_x(value, file, line, 0);
469#else
470			newvalue = sm_strdup_x(value);
471#endif
472			setbitn(id, mac->mac_allocated);
473		}
474		mac->mac_table[id] = newvalue;
475		if (freeit != NULL)
476			sm_free(freeit);
477	}
478	else
479	{
480		if (value == NULL || vclass == A_PERM)
481			newvalue = value;
482		else
483			newvalue = sm_rpool_strdup_x(mac->mac_rpool, value);
484		mac->mac_table[id] = newvalue;
485		if (vclass == A_HEAP)
486			sm_free(value);
487	}
488
489#if _FFR_RESET_MACRO_GLOBALS
490	switch (id)
491	{
492	  case 'j':
493		PSTRSET(MyHostName, value);
494		break;
495	}
496#endif /* _FFR_RESET_MACRO_GLOBALS */
497}
498
499/*
500**  MACSET -- set a named macro to a value (low level)
501**
502**	No fancy storage management; the caller takes full responsibility.
503**	Often used with macget; see also macdefine.
504**
505**	Parameters:
506**		mac -- Macro table.
507**		i -- Macro name, specified as an integer offset.
508**		value -- Macro value: either NULL, or a string.
509*/
510
511void
512macset(mac, i, value)
513	MACROS_T *mac;
514	int i;
515	char *value;
516{
517	if (i < 0 || i > MAXMACROID)
518		return;
519
520	if (tTd(35, 9))
521	{
522		sm_dprintf("macset(%s as ", macname(i));
523		xputs(sm_debug_file(), value);
524		sm_dprintf(")\n");
525	}
526	mac->mac_table[i] = value;
527}
528
529/*
530**  MACVALUE -- return uninterpreted value of a macro.
531**
532**	Does fancy path searching.
533**	The low level counterpart is macget.
534**
535**	Parameters:
536**		n -- the name of the macro.
537**		e -- envelope in which to start looking for the macro.
538**
539**	Returns:
540**		The value of n.
541**
542**	Side Effects:
543**		none.
544*/
545
546char *
547macvalue(n, e)
548	int n;
549	ENVELOPE *e;
550{
551	n = bitidx(n);
552	if (e != NULL && e->e_mci != NULL)
553	{
554		char *p = e->e_mci->mci_macro.mac_table[n];
555
556		if (p != NULL)
557			return p;
558	}
559	while (e != NULL)
560	{
561		char *p = e->e_macro.mac_table[n];
562
563		if (p != NULL)
564			return p;
565		if (e == e->e_parent)
566			break;
567		e = e->e_parent;
568	}
569#if _FFR_BLANKENV_MACV
570	if (LOOKUP_MACRO_IN_BLANKENV && e != &BlankEnvelope)
571	{
572		char *p = BlankEnvelope.e_macro.mac_table[n];
573
574		if (p != NULL)
575			return p;
576	}
577#endif
578	return GlobalMacros.mac_table[n];
579}
580
581/*
582**  MACNAME -- return the name of a macro given its internal id
583**
584**	Parameter:
585**		n -- the id of the macro
586**
587**	Returns:
588**		The name of n.
589**
590**	Side Effects:
591**		none.
592**
593**	WARNING:
594**		Not thread-safe.
595*/
596
597char *
598macname(n)
599	int n;
600{
601	static char mbuf[2];
602
603	n = (int)(unsigned char)n;
604	if (n > MAXMACROID)
605		return "***OUT OF RANGE MACRO***";
606
607	/* if not ASCII printable, look up the name */
608	if (n <= 0x20 || n > 0x7f)
609	{
610		char *p = MacroName[n];
611
612		if (p != NULL)
613			return p;
614		return "***UNDEFINED MACRO***";
615	}
616
617	/* if in the ASCII graphic range, just return the id directly */
618	mbuf[0] = n;
619	mbuf[1] = '\0';
620	return mbuf;
621}
622
623/*
624**  MACID_PARSE -- return id of macro identified by its name
625**
626**	Parameters:
627**		p -- pointer to name string -- either a single
628**			character or {name}.
629**		ep -- filled in with the pointer to the byte
630**			after the name.
631**
632**	Returns:
633**		0 -- An error was detected.
634**		1..MAXMACROID -- The internal id code for this macro.
635**
636**	Side Effects:
637**		If this is a new macro name, a new id is allocated.
638**		On error, syserr is called.
639*/
640
641int
642macid_parse(p, ep)
643	char *p;
644	char **ep;
645{
646	int mid;
647	char *bp;
648	char mbuf[MAXMACNAMELEN + 1];
649
650	if (tTd(35, 14))
651	{
652		sm_dprintf("macid(");
653		xputs(sm_debug_file(), p);
654		sm_dprintf(") => ");
655	}
656
657	if (*p == '\0' || (p[0] == '{' && p[1] == '}'))
658	{
659		syserr("Name required for macro/class");
660		if (ep != NULL)
661			*ep = p;
662		if (tTd(35, 14))
663			sm_dprintf("NULL\n");
664		return 0;
665	}
666	if (*p != '{')
667	{
668		/* the macro is its own code */
669		if (ep != NULL)
670			*ep = p + 1;
671		if (tTd(35, 14))
672		{
673			char buf[2];
674
675			buf[0] = *p;
676			buf[1] = '\0';
677			xputs(sm_debug_file(), buf);
678			sm_dprintf("\n");
679		}
680		return bitidx(*p);
681	}
682	bp = mbuf;
683	while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1])
684	{
685		if (isascii(*p) && (isalnum(*p) || *p == '_'))
686			*bp++ = *p;
687		else
688			syserr("Invalid macro/class character %c", *p);
689	}
690	*bp = '\0';
691	mid = -1;
692	if (*p == '\0')
693	{
694		syserr("Unbalanced { on %s", mbuf);	/* missing } */
695	}
696	else if (*p != '}')
697	{
698		syserr("Macro/class name ({%s}) too long (%d chars max)",
699			mbuf, (int) (sizeof(mbuf) - 1));
700	}
701	else if (mbuf[1] == '\0' && mbuf[0] >= 0x20)
702	{
703		/* ${x} == $x */
704		mid = bitidx(mbuf[0]);
705		p++;
706	}
707	else
708	{
709		STAB *s;
710
711		s = stab(mbuf, ST_MACRO, ST_ENTER);
712		if (s->s_macro != 0)
713			mid = s->s_macro;
714		else
715		{
716			if (NextMacroId > MAXMACROID)
717			{
718				syserr("Macro/class {%s}: too many long names",
719					mbuf);
720				s->s_macro = -1;
721			}
722			else
723			{
724				MacroName[NextMacroId] = s->s_name;
725				s->s_macro = mid = NextMacroId;
726				NextMacroId = NEXTMACROID(NextMacroId);
727			}
728		}
729		p++;
730	}
731	if (ep != NULL)
732		*ep = p;
733	if (mid < 0 || mid > MAXMACROID)
734	{
735		syserr("Unable to assign macro/class ID (mid = 0x%x)", mid);
736		if (tTd(35, 14))
737			sm_dprintf("NULL\n");
738		return 0;
739	}
740	if (tTd(35, 14))
741		sm_dprintf("0x%x\n", mid);
742	return mid;
743}
744
745/*
746**  WORDINCLASS -- tell if a word is in a specific class
747**
748**	Parameters:
749**		str -- the name of the word to look up.
750**		cl -- the class name.
751**
752**	Returns:
753**		true if str can be found in cl.
754**		false otherwise.
755*/
756
757bool
758wordinclass(str, cl)
759	char *str;
760	int cl;
761{
762	STAB *s;
763
764	s = stab(str, ST_CLASS, ST_FIND);
765	return s != NULL && bitnset(bitidx(cl), s->s_class);
766}
767