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 16SM_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 23static 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 */ 38static 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 79int NextMacroId = 1; /* codes for long named macros */ 80/* see sendmail.h: Special characters in rewriting rules. */ 81#else /* _FFR_MORE_MACROS */ 82int NextMacroId = 0240; /* codes for long named macros */ 83#define NEXTMACROID(mid) ((mid) + 1) 84#endif /* _FFR_MORE_MACROS */ 85 86/* 87** INITMACROS -- initialize the macro system 88** 89** This just involves defining some macros that are actually 90** used internally as metasymbols to be themselves. 91** 92** Parameters: 93** none. 94** 95** Returns: 96** none. 97** 98** Side Effects: 99** initializes several macros to be themselves. 100*/ 101 102struct metamac MetaMacros[] = 103{ 104 /* LHS pattern matching characters */ 105 { '*', MATCHZANY }, { '+', MATCHANY }, { '-', MATCHONE }, 106 { '=', MATCHCLASS }, { '~', MATCHNCLASS }, 107 108 /* these are RHS metasymbols */ 109 { '#', CANONNET }, { '@', CANONHOST }, { ':', CANONUSER }, 110 { '>', CALLSUBR }, 111 112 /* the conditional operations */ 113 { '?', CONDIF }, { '|', CONDELSE }, { '.', CONDFI }, 114 115 /* the hostname lookup characters */ 116 { '[', HOSTBEGIN }, { ']', HOSTEND }, 117 { '(', LOOKUPBEGIN }, { ')', LOOKUPEND }, 118 119 /* miscellaneous control characters */ 120 { '&', MACRODEXPAND }, 121 122 { '\0', '\0' } 123}; 124 125#define MACBINDING(name, mid) \ 126 stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \ 127 MacroName[mid] = name; 128 129void 130initmacros(e) 131 ENVELOPE *e; 132{ 133 struct metamac *m; 134 int c; 135 char buf[5]; 136 137 for (m = MetaMacros; m->metaname != '\0'; m++) 138 { 139 buf[0] = m->metaval; 140 buf[1] = '\0'; 141 macdefine(&e->e_macro, A_TEMP, m->metaname, buf); 142 } 143 buf[0] = MATCHREPL; 144 buf[2] = '\0'; 145 for (c = '0'; c <= '9'; c++) 146 { 147 buf[1] = c; 148 macdefine(&e->e_macro, A_TEMP, c, buf); 149 } 150 151 /* set defaults for some macros sendmail will use later */ 152 macdefine(&e->e_macro, A_PERM, 'n', "MAILER-DAEMON"); 153 154 /* set up external names for some internal macros */ 155 MACBINDING("opMode", MID_OPMODE); 156 /*XXX should probably add equivalents for all short macros here XXX*/ 157} 158 159/* 160** EXPAND/DOEXPAND -- macro expand a string using $x escapes. 161** (including conditionals, e.g., $?x Y $| N $.) 162** 163** Parameters: 164** s -- the string to expand. [i] 165** buf -- the place to put the expansion. [i] 166** bufsize -- the size of the buffer. 167** explevel -- the depth of expansion (doexpand only) 168** e -- envelope in which to work. 169** 170** Returns: 171** none. 172*/ 173 174static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *)); 175 176static void 177doexpand(s, buf, bufsize, explevel, e) 178 char *s; 179 char *buf; 180 size_t bufsize; 181 int explevel; 182 ENVELOPE *e; 183{ 184 char *xp; 185 char *q; 186 bool skipping; /* set if conditionally skipping output */ 187 bool recurse; /* set if recursion required */ 188 size_t i; 189 int skiplev; /* skipping nesting level */ 190 int iflev; /* if nesting level */ 191 bool quotenext; /* quote the following character */ 192 char xbuf[MACBUFSIZE]; 193 194 if (tTd(35, 24)) 195 { 196 sm_dprintf("expand("); 197 xputs(sm_debug_file(), s); 198 sm_dprintf(")\n"); 199 } 200 201 recurse = false; 202 skipping = false; 203 skiplev = 0; 204 iflev = 0; 205 quotenext = false; 206 if (s == NULL) 207 s = ""; 208 for (xp = xbuf; *s != '\0'; s++) 209 { 210 int c; 211 212 /* 213 ** Check for non-ordinary (special?) character. 214 ** 'q' will be the interpolated quantity. 215 */ 216 217 q = NULL; 218 c = *s & 0377; 219 220 if (quotenext) 221 { 222 quotenext = false; 223 goto simpleinterpolate; 224 } 225 226 switch (c) 227 { 228 case CONDIF: /* see if var set */ 229 iflev++; 230 c = *++s & 0377; 231 if (skipping) 232 skiplev++; 233 else 234 { 235 char *mv; 236 237 mv = macvalue(c, e); 238 skipping = (mv == NULL || *mv == '\0'); 239 } 240 continue; 241 242 case CONDELSE: /* change state of skipping */ 243 if (iflev == 0) 244 break; /* XXX: error */ 245 if (skiplev == 0) 246 skipping = !skipping; 247 continue; 248 249 case CONDFI: /* stop skipping */ 250 if (iflev == 0) 251 break; /* XXX: error */ 252 iflev--; 253 if (skiplev == 0) 254 skipping = false; 255 if (skipping) 256 skiplev--; 257 continue; 258 259 case MACROEXPAND: /* macro interpolation */ 260 c = bitidx(*++s); 261 if (c != '\0') 262 q = macvalue(c, e); 263 else 264 { 265 s--; 266 q = NULL; 267 } 268 if (q == NULL) 269 continue; 270 break; 271 272 case METAQUOTE: 273 /* next octet completely quoted */ 274 quotenext = true; 275 break; 276 } 277 278 /* 279 ** Interpolate q or output one character 280 */ 281 282 simpleinterpolate: 283 if (skipping || xp >= &xbuf[sizeof(xbuf) - 1]) 284 continue; 285 if (q == NULL) 286 *xp++ = c; 287 else 288 { 289 /* copy to end of q or max space remaining in buf */ 290 bool hiderecurse = false; 291 292 while ((c = *q++) != '\0' && 293 xp < &xbuf[sizeof(xbuf) - 1]) 294 { 295 /* check for any sendmail metacharacters */ 296 if (!hiderecurse && (c & 0340) == 0200) 297 recurse = true; 298 *xp++ = c; 299 300 /* give quoted characters a free ride */ 301 hiderecurse = (c & 0377) == METAQUOTE; 302 } 303 } 304 } 305 *xp = '\0'; 306 307 if (tTd(35, 28)) 308 { 309 sm_dprintf("expand(%d) ==> ", explevel); 310 xputs(sm_debug_file(), xbuf); 311 sm_dprintf("\n"); 312 } 313 314 /* recurse as appropriate */ 315 if (recurse) 316 { 317 if (explevel < MaxMacroRecursion) 318 { 319 doexpand(xbuf, buf, bufsize, explevel + 1, e); 320 return; 321 } 322 syserr("expand: recursion too deep (%d max)", 323 MaxMacroRecursion); 324 } 325 326 /* copy results out */ 327 if (explevel == 0) 328 (void) sm_strlcpy(buf, xbuf, bufsize); 329 else 330 { 331 /* leave in internal form */ 332 i = xp - xbuf; 333 if (i >= bufsize) 334 i = bufsize - 1; 335 memmove(buf, xbuf, i); 336 buf[i] = '\0'; 337 } 338 339 if (tTd(35, 24)) 340 { 341 sm_dprintf("expand ==> "); 342 xputs(sm_debug_file(), buf); 343 sm_dprintf("\n"); 344 } 345} 346 347void 348expand(s, buf, bufsize, e) 349 char *s; 350 char *buf; 351 size_t bufsize; 352 ENVELOPE *e; 353{ 354 doexpand(s, buf, bufsize, 0, e); 355} 356 357/* 358** MACTABCLEAR -- clear entire macro table 359** 360** Parameters: 361** mac -- Macro table. 362** 363** Returns: 364** none. 365** 366** Side Effects: 367** clears entire mac structure including rpool pointer! 368*/ 369 370void 371mactabclear(mac) 372 MACROS_T *mac; 373{ 374 int i; 375 376 if (mac->mac_rpool == NULL) 377 { 378 for (i = 0; i < MAXMACROID; i++) 379 SM_FREE(mac->mac_table[i]); 380 } 381 memset((char *) mac, '\0', sizeof(*mac)); 382} 383 384/* 385** MACDEFINE -- bind a macro name to a value 386** 387** Set a macro to a value, with fancy storage management. 388** macdefine will make a copy of the value, if required, 389** and will ensure that the storage for the previous value 390** is not leaked. 391** 392** Parameters: 393** mac -- Macro table. 394** vclass -- storage class of 'value', ignored if value==NULL. 395** A_HEAP means that the value was allocated by 396** malloc, and that macdefine owns the storage. 397** A_TEMP means that value points to temporary storage, 398** and thus macdefine needs to make a copy. 399** A_PERM means that value points to storage that 400** will remain allocated and unchanged for 401** at least the lifetime of mac. Use A_PERM if: 402** -- value == NULL, 403** -- value points to a string literal, 404** -- value was allocated from mac->mac_rpool 405** or (in the case of an envelope macro) 406** from e->e_rpool, 407** -- in the case of an envelope macro, 408** value is a string member of the envelope 409** such as e->e_sender. 410** id -- Macro id. This is a single character macro name 411** such as 'g', or a value returned by macid(). 412** value -- Macro value: either NULL, or a string. 413** 414** Returns: 415** none. 416*/ 417 418void 419#if SM_HEAP_CHECK 420macdefine_tagged(mac, vclass, id, value, file, line, grp) 421#else 422macdefine(mac, vclass, id, value) 423#endif 424 MACROS_T *mac; 425 ARGCLASS_T vclass; 426 int id; 427 char *value; 428#if SM_HEAP_CHECK 429 char *file; 430 int line; 431 int grp; 432#endif 433{ 434 char *newvalue; 435 436 if (id < 0 || id > MAXMACROID) 437 return; 438 439 if (tTd(35, 9)) 440 { 441 sm_dprintf("%sdefine(%s as ", 442 mac->mac_table[id] == NULL ? "" : "re", macname(id)); 443 xputs(sm_debug_file(), value); 444 sm_dprintf(")\n"); 445 } 446#if USE_EAI && 0 447// if (('j' == id || 'm' == id) && !addr_is_ascii(value)) 448// return an error/warning to caller and let them handle it. 449#endif 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** Returns: 511** none. 512*/ 513 514void 515macset(mac, i, value) 516 MACROS_T *mac; 517 int i; 518 char *value; 519{ 520 if (i < 0 || i > MAXMACROID) 521 return; 522 523 if (tTd(35, 9)) 524 { 525 sm_dprintf("macset(%s as ", macname(i)); 526 xputs(sm_debug_file(), value); 527 sm_dprintf(")\n"); 528 } 529 mac->mac_table[i] = value; 530} 531 532/* 533** MACVALUE -- return uninterpreted value of a macro. 534** 535** Does fancy path searching. 536** The low level counterpart is macget. 537** 538** Parameters: 539** n -- the name of the macro. 540** e -- envelope in which to start looking for the macro. 541** 542** Returns: 543** The value of n. 544** 545** Side Effects: 546** none. 547*/ 548 549char * 550macvalue(n, e) 551 int n; 552 ENVELOPE *e; 553{ 554 n = bitidx(n); 555 if (e != NULL && e->e_mci != NULL) 556 { 557 char *p = e->e_mci->mci_macro.mac_table[n]; 558 559 if (p != NULL) 560 return p; 561 } 562 while (e != NULL) 563 { 564 char *p = e->e_macro.mac_table[n]; 565 566 if (p != NULL) 567 return p; 568 if (e == e->e_parent) 569 break; 570 e = e->e_parent; 571 } 572#if _FFR_BLANKENV_MACV 573 if (LOOKUP_MACRO_IN_BLANKENV && e != &BlankEnvelope) 574 { 575 char *p = BlankEnvelope.e_macro.mac_table[n]; 576 577 if (p != NULL) 578 return p; 579 } 580#endif 581 return GlobalMacros.mac_table[n]; 582} 583 584/* 585** MACNAME -- return the name of a macro given its internal id 586** 587** Parameter: 588** n -- the id of the macro 589** 590** Returns: 591** The name of n. 592** 593** Side Effects: 594** none. 595** 596** WARNING: 597** Not thread-safe. 598*/ 599 600char * 601macname(n) 602 int n; 603{ 604 static char mbuf[2]; 605 606 n = (int)(unsigned char)n; 607 if (n > MAXMACROID) 608 return "***OUT OF RANGE MACRO***"; 609 610 /* if not ASCII printable, look up the name */ 611 if (n <= 0x20 || n > 0x7f) 612 { 613 char *p = MacroName[n]; 614 615 if (p != NULL) 616 return p; 617 return "***UNDEFINED MACRO***"; 618 } 619 620 /* if in the ASCII graphic range, just return the id directly */ 621 mbuf[0] = n; 622 mbuf[1] = '\0'; 623 return mbuf; 624} 625 626/* 627** MACID_PARSE -- return id of macro identified by its name 628** 629** Parameters: 630** p -- pointer to name string -- either a single 631** character or {name}. 632** ep -- filled in with the pointer to the byte 633** after the name. 634** 635** Returns: 636** 0 -- An error was detected. 637** 1..MAXMACROID -- The internal id code for this macro. 638** 639** Side Effects: 640** If this is a new macro name, a new id is allocated. 641** On error, syserr is called. 642*/ 643 644int 645macid_parse(p, ep) 646 char *p; 647 char **ep; 648{ 649 int mid; 650 char *bp; 651 char mbuf[MAXMACNAMELEN + 1]; 652 653 if (tTd(35, 14)) 654 { 655 sm_dprintf("macid("); 656 xputs(sm_debug_file(), p); 657 sm_dprintf(") => "); 658 } 659 660 if (*p == '\0' || (p[0] == '{' && p[1] == '}')) 661 { 662 syserr("Name required for macro/class"); 663 if (ep != NULL) 664 *ep = p; 665 if (tTd(35, 14)) 666 sm_dprintf("NULL\n"); 667 return 0; 668 } 669 if (*p != '{') 670 { 671 /* the macro is its own code */ 672 if (ep != NULL) 673 *ep = p + 1; 674 if (tTd(35, 14)) 675 { 676 char buf[2]; 677 678 buf[0] = *p; 679 buf[1] = '\0'; 680 xputs(sm_debug_file(), buf); 681 sm_dprintf("\n"); 682 } 683 return bitidx(*p); 684 } 685 bp = mbuf; 686 while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1]) 687 { 688 if (isascii(*p) && (isalnum(*p) || *p == '_')) 689 *bp++ = *p; 690 else 691 syserr("Invalid macro/class character %c", *p); 692 } 693 *bp = '\0'; 694 mid = -1; 695 if (*p == '\0') 696 { 697 syserr("Unbalanced { on %s", mbuf); /* missing } */ 698 } 699 else if (*p != '}') 700 { 701 syserr("Macro/class name ({%s}) too long (%d chars max)", 702 mbuf, (int) (sizeof(mbuf) - 1)); 703 } 704 else if (mbuf[1] == '\0' && mbuf[0] >= 0x20) 705 { 706 /* ${x} == $x */ 707 mid = bitidx(mbuf[0]); 708 p++; 709 } 710 else 711 { 712 STAB *s; 713 714 s = stab(mbuf, ST_MACRO, ST_ENTER); 715 if (s->s_macro != 0) 716 mid = s->s_macro; 717 else 718 { 719 if (NextMacroId > MAXMACROID) 720 { 721 syserr("Macro/class {%s}: too many long names", 722 mbuf); 723 s->s_macro = -1; 724 } 725 else 726 { 727 MacroName[NextMacroId] = s->s_name; 728 s->s_macro = mid = NextMacroId; 729 NextMacroId = NEXTMACROID(NextMacroId); 730 } 731 } 732 p++; 733 } 734 if (ep != NULL) 735 *ep = p; 736 if (mid < 0 || mid > MAXMACROID) 737 { 738 syserr("Unable to assign macro/class ID (mid = 0x%x)", mid); 739 if (tTd(35, 14)) 740 sm_dprintf("NULL\n"); 741 return 0; 742 } 743 if (tTd(35, 14)) 744 sm_dprintf("0x%x\n", mid); 745 return mid; 746} 747 748/* 749** WORDINCLASS -- tell if a word is in a specific class 750** 751** Parameters: 752** str -- the name of the word to look up. 753** cl -- the class name. 754** 755** Returns: 756** true if str can be found in cl. 757** false otherwise. 758*/ 759 760bool 761wordinclass(str, cl) 762 char *str; 763 int cl; 764{ 765 STAB *s; 766#if _FFR_DYN_CLASS 767 MAP *map; 768 int status; 769 char *p; 770 char key[MAXLINE]; 771 772 p = macname(cl); 773 s = stab(p, ST_DYNMAP, ST_FIND); 774 if (NULL == s) 775 { 776#endif 777 s = stab(str, ST_CLASS, ST_FIND); 778 return s != NULL && bitnset(bitidx(cl), s->s_class); 779#if _FFR_DYN_CLASS 780 } 781 map = &s->s_dynclass; 782 SM_REQUIRE(NULL != map); 783 SM_REQUIRE(!SM_IS_EMPTY(str)); 784 if (bitset(MF_OPENBOGUS, map->map_mflags)) 785 { 786 /* need to set some error! */ 787 return false; 788 } 789 790 key[0] = '\0'; 791 if (!SM_IS_EMPTY(map->map_tag)) 792 { 793 sm_strlcpy(key, map->map_tag, sizeof(key)); 794 sm_strlcat(key, ":", sizeof(key)); 795 } 796 sm_strlcat(key, str, sizeof(key)); 797 status = EX_OK; 798 p = (map->map_class->map_lookup)(map, key, NULL, &status); 799 if (NULL != p) 800 return true; 801 if ((EX_OK == status && NULL == p) || EX_NOTFOUND == status) 802 return false; 803 804 sm_syslog(LOG_WARNING, CurEnv->e_id, 805 "dynamic class: A{%s}: map lookup failed: key=%s, status=%d", 806 map->map_mname, key, status); 807 808 /* Note: this error is shown to the client, so do not "leak" info */ 809 usrerr("451 4.3.1 temporary error"); 810 811 return false; 812#endif 813} 814