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
initmacros(e)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
doexpand(s,buf,bufsize,explevel,e)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
expand(s,buf,bufsize,e)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
mactabclear(mac)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
macdefine_tagged(mac,vclass,id,value,file,line,grp)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