xref: /freebsd/contrib/sendmail/src/macro.c (revision 9f44a47fd07924afc035991af15d84e6585dea4f)
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 
16 SM_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 
23 static 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 */
38 static 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 
79 int		NextMacroId = 1;	/* codes for long named macros */
80 /* see sendmail.h: Special characters in rewriting rules. */
81 #else /* _FFR_MORE_MACROS */
82 int		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 
103 struct 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 
130 void
131 initmacros(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 **	(including conditionals, e.g., $?x Y $| N $.)
163 **
164 **	Parameters:
165 **		s -- the string to expand. [i]
166 **		buf -- the place to put the expansion. [i]
167 **		bufsize -- the size of the buffer.
168 **		explevel -- the depth of expansion (doexpand only)
169 **		e -- envelope in which to work.
170 **
171 **	Returns:
172 **		none.
173 */
174 
175 static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *));
176 
177 static void
178 doexpand(s, buf, bufsize, explevel, e)
179 	char *s;
180 	char *buf;
181 	size_t bufsize;
182 	int explevel;
183 	ENVELOPE *e;
184 {
185 	char *xp;
186 	char *q;
187 	bool skipping;		/* set if conditionally skipping output */
188 	bool recurse;		/* set if recursion required */
189 	size_t i;
190 	int skiplev;		/* skipping nesting level */
191 	int iflev;		/* if nesting level */
192 	bool quotenext;		/* quote the following character */
193 	char xbuf[MACBUFSIZE];
194 
195 	if (tTd(35, 24))
196 	{
197 		sm_dprintf("expand(");
198 		xputs(sm_debug_file(), s);
199 		sm_dprintf(")\n");
200 	}
201 
202 	recurse = false;
203 	skipping = false;
204 	skiplev = 0;
205 	iflev = 0;
206 	quotenext = false;
207 	if (s == NULL)
208 		s = "";
209 	for (xp = xbuf; *s != '\0'; s++)
210 	{
211 		int c;
212 
213 		/*
214 		**  Check for non-ordinary (special?) character.
215 		**	'q' will be the interpolated quantity.
216 		*/
217 
218 		q = NULL;
219 		c = *s & 0377;
220 
221 		if (quotenext)
222 		{
223 			quotenext = false;
224 			goto simpleinterpolate;
225 		}
226 
227 		switch (c)
228 		{
229 		  case CONDIF:		/* see if var set */
230 			iflev++;
231 			c = *++s & 0377;
232 			if (skipping)
233 				skiplev++;
234 			else
235 			{
236 				char *mv;
237 
238 				mv = macvalue(c, e);
239 				skipping = (mv == NULL || *mv == '\0');
240 			}
241 			continue;
242 
243 		  case CONDELSE:	/* change state of skipping */
244 			if (iflev == 0)
245 				break;	/* XXX: error */
246 			if (skiplev == 0)
247 				skipping = !skipping;
248 			continue;
249 
250 		  case CONDFI:		/* stop skipping */
251 			if (iflev == 0)
252 				break;	/* XXX: error */
253 			iflev--;
254 			if (skiplev == 0)
255 				skipping = false;
256 			if (skipping)
257 				skiplev--;
258 			continue;
259 
260 		  case MACROEXPAND:	/* macro interpolation */
261 			c = bitidx(*++s);
262 			if (c != '\0')
263 				q = macvalue(c, e);
264 			else
265 			{
266 				s--;
267 				q = NULL;
268 			}
269 			if (q == NULL)
270 				continue;
271 			break;
272 
273 		  case METAQUOTE:
274 			/* next octet completely quoted */
275 			quotenext = true;
276 			break;
277 		}
278 
279 		/*
280 		**  Interpolate q or output one character
281 		*/
282 
283   simpleinterpolate:
284 		if (skipping || xp >= &xbuf[sizeof(xbuf) - 1])
285 			continue;
286 		if (q == NULL)
287 			*xp++ = c;
288 		else
289 		{
290 			/* copy to end of q or max space remaining in buf */
291 			bool hiderecurse = false;
292 
293 			while ((c = *q++) != '\0' &&
294 				xp < &xbuf[sizeof(xbuf) - 1])
295 			{
296 				/* check for any sendmail metacharacters */
297 				if (!hiderecurse && (c & 0340) == 0200)
298 					recurse = true;
299 				*xp++ = c;
300 
301 				/* give quoted characters a free ride */
302 				hiderecurse = (c & 0377) == METAQUOTE;
303 			}
304 		}
305 	}
306 	*xp = '\0';
307 
308 	if (tTd(35, 28))
309 	{
310 		sm_dprintf("expand(%d) ==> ", explevel);
311 		xputs(sm_debug_file(), xbuf);
312 		sm_dprintf("\n");
313 	}
314 
315 	/* recurse as appropriate */
316 	if (recurse)
317 	{
318 		if (explevel < MaxMacroRecursion)
319 		{
320 			doexpand(xbuf, buf, bufsize, explevel + 1, e);
321 			return;
322 		}
323 		syserr("expand: recursion too deep (%d max)",
324 			MaxMacroRecursion);
325 	}
326 
327 	/* copy results out */
328 	if (explevel == 0)
329 		(void) sm_strlcpy(buf, xbuf, bufsize);
330 	else
331 	{
332 		/* leave in internal form */
333 		i = xp - xbuf;
334 		if (i >= bufsize)
335 			i = bufsize - 1;
336 		memmove(buf, xbuf, i);
337 		buf[i] = '\0';
338 	}
339 
340 	if (tTd(35, 24))
341 	{
342 		sm_dprintf("expand ==> ");
343 		xputs(sm_debug_file(), buf);
344 		sm_dprintf("\n");
345 	}
346 }
347 
348 void
349 expand(s, buf, bufsize, e)
350 	char *s;
351 	char *buf;
352 	size_t bufsize;
353 	ENVELOPE *e;
354 {
355 	doexpand(s, buf, bufsize, 0, e);
356 }
357 
358 /*
359 **  MACTABCLEAR -- clear entire macro table
360 **
361 **	Parameters:
362 **		mac -- Macro table.
363 **
364 **	Returns:
365 **		none.
366 **
367 **	Side Effects:
368 **		clears entire mac structure including rpool pointer!
369 */
370 
371 void
372 mactabclear(mac)
373 	MACROS_T *mac;
374 {
375 	int i;
376 
377 	if (mac->mac_rpool == NULL)
378 	{
379 		for (i = 0; i < MAXMACROID; i++)
380 			SM_FREE(mac->mac_table[i]);
381 	}
382 	memset((char *) mac, '\0', sizeof(*mac));
383 }
384 
385 /*
386 **  MACDEFINE -- bind a macro name to a value
387 **
388 **	Set a macro to a value, with fancy storage management.
389 **	macdefine will make a copy of the value, if required,
390 **	and will ensure that the storage for the previous value
391 **	is not leaked.
392 **
393 **	Parameters:
394 **		mac -- Macro table.
395 **		vclass -- storage class of 'value', ignored if value==NULL.
396 **			A_HEAP	means that the value was allocated by
397 **				malloc, and that macdefine owns the storage.
398 **			A_TEMP	means that value points to temporary storage,
399 **				and thus macdefine needs to make a copy.
400 **			A_PERM	means that value points to storage that
401 **				will remain allocated and unchanged for
402 **				at least the lifetime of mac.  Use A_PERM if:
403 **				-- value == NULL,
404 **				-- value points to a string literal,
405 **				-- value was allocated from mac->mac_rpool
406 **				   or (in the case of an envelope macro)
407 **				   from e->e_rpool,
408 **				-- in the case of an envelope macro,
409 **				   value is a string member of the envelope
410 **				   such as e->e_sender.
411 **		id -- Macro id.  This is a single character macro name
412 **			such as 'g', or a value returned by macid().
413 **		value -- Macro value: either NULL, or a string.
414 */
415 
416 void
417 #if SM_HEAP_CHECK
418 macdefine_tagged(mac, vclass, id, value, file, line, grp)
419 #else
420 macdefine(mac, vclass, id, value)
421 #endif
422 	MACROS_T *mac;
423 	ARGCLASS_T vclass;
424 	int id;
425 	char *value;
426 #if SM_HEAP_CHECK
427 	char *file;
428 	int line;
429 	int grp;
430 #endif
431 {
432 	char *newvalue;
433 
434 	if (id < 0 || id > MAXMACROID)
435 		return;
436 
437 	if (tTd(35, 9))
438 	{
439 		sm_dprintf("%sdefine(%s as ",
440 			mac->mac_table[id] == NULL ? "" : "re", macname(id));
441 		xputs(sm_debug_file(), value);
442 		sm_dprintf(")\n");
443 	}
444 #if USE_EAI && 0
445 	if (('j' == id || 'm' == id) && !addr_is_ascii(value))
446 		return an error/warning to caller and let them handle it.
447 #endif
448 
449 	if (mac->mac_rpool == NULL)
450 	{
451 		char *freeit = NULL;
452 
453 		if (mac->mac_table[id] != NULL &&
454 		    bitnset(id, mac->mac_allocated))
455 			freeit = mac->mac_table[id];
456 
457 		if (value == NULL || vclass == A_HEAP)
458 		{
459 			sm_heap_checkptr_tagged(value, file, line);
460 			newvalue = value;
461 			clrbitn(id, mac->mac_allocated);
462 		}
463 		else
464 		{
465 #if SM_HEAP_CHECK
466 			newvalue = sm_strdup_tagged_x(value, file, line, 0);
467 #else
468 			newvalue = sm_strdup_x(value);
469 #endif
470 			setbitn(id, mac->mac_allocated);
471 		}
472 		mac->mac_table[id] = newvalue;
473 		if (freeit != NULL)
474 			sm_free(freeit);
475 	}
476 	else
477 	{
478 		if (value == NULL || vclass == A_PERM)
479 			newvalue = value;
480 		else
481 			newvalue = sm_rpool_strdup_x(mac->mac_rpool, value);
482 		mac->mac_table[id] = newvalue;
483 		if (vclass == A_HEAP)
484 			sm_free(value);
485 	}
486 
487 #if _FFR_RESET_MACRO_GLOBALS
488 	switch (id)
489 	{
490 	  case 'j':
491 		PSTRSET(MyHostName, value);
492 		break;
493 	}
494 #endif /* _FFR_RESET_MACRO_GLOBALS */
495 }
496 
497 /*
498 **  MACSET -- set a named macro to a value (low level)
499 **
500 **	No fancy storage management; the caller takes full responsibility.
501 **	Often used with macget; see also macdefine.
502 **
503 **	Parameters:
504 **		mac -- Macro table.
505 **		i -- Macro name, specified as an integer offset.
506 **		value -- Macro value: either NULL, or a string.
507 */
508 
509 void
510 macset(mac, i, value)
511 	MACROS_T *mac;
512 	int i;
513 	char *value;
514 {
515 	if (i < 0 || i > MAXMACROID)
516 		return;
517 
518 	if (tTd(35, 9))
519 	{
520 		sm_dprintf("macset(%s as ", macname(i));
521 		xputs(sm_debug_file(), value);
522 		sm_dprintf(")\n");
523 	}
524 	mac->mac_table[i] = value;
525 }
526 
527 /*
528 **  MACVALUE -- return uninterpreted value of a macro.
529 **
530 **	Does fancy path searching.
531 **	The low level counterpart is macget.
532 **
533 **	Parameters:
534 **		n -- the name of the macro.
535 **		e -- envelope in which to start looking for the macro.
536 **
537 **	Returns:
538 **		The value of n.
539 **
540 **	Side Effects:
541 **		none.
542 */
543 
544 char *
545 macvalue(n, e)
546 	int n;
547 	ENVELOPE *e;
548 {
549 	n = bitidx(n);
550 	if (e != NULL && e->e_mci != NULL)
551 	{
552 		char *p = e->e_mci->mci_macro.mac_table[n];
553 
554 		if (p != NULL)
555 			return p;
556 	}
557 	while (e != NULL)
558 	{
559 		char *p = e->e_macro.mac_table[n];
560 
561 		if (p != NULL)
562 			return p;
563 		if (e == e->e_parent)
564 			break;
565 		e = e->e_parent;
566 	}
567 #if _FFR_BLANKENV_MACV
568 	if (LOOKUP_MACRO_IN_BLANKENV && e != &BlankEnvelope)
569 	{
570 		char *p = BlankEnvelope.e_macro.mac_table[n];
571 
572 		if (p != NULL)
573 			return p;
574 	}
575 #endif
576 	return GlobalMacros.mac_table[n];
577 }
578 
579 /*
580 **  MACNAME -- return the name of a macro given its internal id
581 **
582 **	Parameter:
583 **		n -- the id of the macro
584 **
585 **	Returns:
586 **		The name of n.
587 **
588 **	Side Effects:
589 **		none.
590 **
591 **	WARNING:
592 **		Not thread-safe.
593 */
594 
595 char *
596 macname(n)
597 	int n;
598 {
599 	static char mbuf[2];
600 
601 	n = (int)(unsigned char)n;
602 	if (n > MAXMACROID)
603 		return "***OUT OF RANGE MACRO***";
604 
605 	/* if not ASCII printable, look up the name */
606 	if (n <= 0x20 || n > 0x7f)
607 	{
608 		char *p = MacroName[n];
609 
610 		if (p != NULL)
611 			return p;
612 		return "***UNDEFINED MACRO***";
613 	}
614 
615 	/* if in the ASCII graphic range, just return the id directly */
616 	mbuf[0] = n;
617 	mbuf[1] = '\0';
618 	return mbuf;
619 }
620 
621 /*
622 **  MACID_PARSE -- return id of macro identified by its name
623 **
624 **	Parameters:
625 **		p -- pointer to name string -- either a single
626 **			character or {name}.
627 **		ep -- filled in with the pointer to the byte
628 **			after the name.
629 **
630 **	Returns:
631 **		0 -- An error was detected.
632 **		1..MAXMACROID -- The internal id code for this macro.
633 **
634 **	Side Effects:
635 **		If this is a new macro name, a new id is allocated.
636 **		On error, syserr is called.
637 */
638 
639 int
640 macid_parse(p, ep)
641 	char *p;
642 	char **ep;
643 {
644 	int mid;
645 	char *bp;
646 	char mbuf[MAXMACNAMELEN + 1];
647 
648 	if (tTd(35, 14))
649 	{
650 		sm_dprintf("macid(");
651 		xputs(sm_debug_file(), p);
652 		sm_dprintf(") => ");
653 	}
654 
655 	if (*p == '\0' || (p[0] == '{' && p[1] == '}'))
656 	{
657 		syserr("Name required for macro/class");
658 		if (ep != NULL)
659 			*ep = p;
660 		if (tTd(35, 14))
661 			sm_dprintf("NULL\n");
662 		return 0;
663 	}
664 	if (*p != '{')
665 	{
666 		/* the macro is its own code */
667 		if (ep != NULL)
668 			*ep = p + 1;
669 		if (tTd(35, 14))
670 		{
671 			char buf[2];
672 
673 			buf[0] = *p;
674 			buf[1] = '\0';
675 			xputs(sm_debug_file(), buf);
676 			sm_dprintf("\n");
677 		}
678 		return bitidx(*p);
679 	}
680 	bp = mbuf;
681 	while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1])
682 	{
683 		if (isascii(*p) && (isalnum(*p) || *p == '_'))
684 			*bp++ = *p;
685 		else
686 			syserr("Invalid macro/class character %c", *p);
687 	}
688 	*bp = '\0';
689 	mid = -1;
690 	if (*p == '\0')
691 	{
692 		syserr("Unbalanced { on %s", mbuf);	/* missing } */
693 	}
694 	else if (*p != '}')
695 	{
696 		syserr("Macro/class name ({%s}) too long (%d chars max)",
697 			mbuf, (int) (sizeof(mbuf) - 1));
698 	}
699 	else if (mbuf[1] == '\0' && mbuf[0] >= 0x20)
700 	{
701 		/* ${x} == $x */
702 		mid = bitidx(mbuf[0]);
703 		p++;
704 	}
705 	else
706 	{
707 		STAB *s;
708 
709 		s = stab(mbuf, ST_MACRO, ST_ENTER);
710 		if (s->s_macro != 0)
711 			mid = s->s_macro;
712 		else
713 		{
714 			if (NextMacroId > MAXMACROID)
715 			{
716 				syserr("Macro/class {%s}: too many long names",
717 					mbuf);
718 				s->s_macro = -1;
719 			}
720 			else
721 			{
722 				MacroName[NextMacroId] = s->s_name;
723 				s->s_macro = mid = NextMacroId;
724 				NextMacroId = NEXTMACROID(NextMacroId);
725 			}
726 		}
727 		p++;
728 	}
729 	if (ep != NULL)
730 		*ep = p;
731 	if (mid < 0 || mid > MAXMACROID)
732 	{
733 		syserr("Unable to assign macro/class ID (mid = 0x%x)", mid);
734 		if (tTd(35, 14))
735 			sm_dprintf("NULL\n");
736 		return 0;
737 	}
738 	if (tTd(35, 14))
739 		sm_dprintf("0x%x\n", mid);
740 	return mid;
741 }
742 
743 /*
744 **  WORDINCLASS -- tell if a word is in a specific class
745 **
746 **	Parameters:
747 **		str -- the name of the word to look up.
748 **		cl -- the class name.
749 **
750 **	Returns:
751 **		true if str can be found in cl.
752 **		false otherwise.
753 */
754 
755 bool
756 wordinclass(str, cl)
757 	char *str;
758 	int cl;
759 {
760 	STAB *s;
761 
762 	s = stab(str, ST_CLASS, ST_FIND);
763 	return s != NULL && bitnset(bitidx(cl), s->s_class);
764 }
765