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
initmacros(e)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
doexpand(s,buf,bufsize,explevel,e)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
expand(s,buf,bufsize,e)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
macdefine_tagged(mac,vclass,id,value,file,line,grp)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
macset(mac,i,value)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 *
macvalue(n,e)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 *
macname(n)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
macid_parse(p,ep)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
wordinclass(str,cl)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