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 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 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 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 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 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