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