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 ** 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 102 struct 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 129 void 130 initmacros(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 174 static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *)); 175 176 static void 177 doexpand(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 347 void 348 expand(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 370 void 371 mactabclear(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 418 void 419 #if SM_HEAP_CHECK 420 macdefine_tagged(mac, vclass, id, value, file, line, grp) 421 #else 422 macdefine(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 514 void 515 macset(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 549 char * 550 macvalue(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 600 char * 601 macname(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 644 int 645 macid_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 760 bool 761 wordinclass(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