xref: /freebsd/contrib/sendmail/src/macro.c (revision cfd6422a5217410fbd66f7a7a8a64d9d85e61229)
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 **
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 
181 static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *));
182 
183 static void
184 doexpand(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 
354 void
355 expand(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 
377 void
378 mactabclear(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 
422 void
423 #if SM_HEAP_CHECK
424 macdefine_tagged(mac, vclass, id, value, file, line, grp)
425 #else /* SM_HEAP_CHECK */
426 macdefine(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 
511 void
512 macset(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 
546 char *
547 macvalue(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 
597 char *
598 macname(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 
641 int
642 macid_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 
757 bool
758 wordinclass(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