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 ** 163 ** After expansion, the expansion will be in external form (that is, 164 ** there will be no sendmail metacharacters and METAQUOTEs will have 165 ** been stripped out). 166 ** 167 ** Parameters: 168 ** s -- the string to expand. 169 ** buf -- the place to put the expansion. 170 ** bufsize -- the size of the buffer. 171 ** explevel -- the depth of expansion (doexpand only) 172 ** e -- envelope in which to work. 173 ** 174 ** Returns: 175 ** none. 176 ** 177 ** Side Effects: 178 ** none. 179 */ 180 181 static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *)); 182 183 static void 184 doexpand(s, buf, bufsize, explevel, e) 185 char *s; 186 char *buf; 187 size_t bufsize; 188 int explevel; 189 ENVELOPE *e; 190 { 191 char *xp; 192 char *q; 193 bool skipping; /* set if conditionally skipping output */ 194 bool recurse; /* set if recursion required */ 195 size_t i; 196 int skiplev; /* skipping nesting level */ 197 int iflev; /* if nesting level */ 198 bool quotenext; /* quote the following character */ 199 char xbuf[MACBUFSIZE]; 200 201 if (tTd(35, 24)) 202 { 203 sm_dprintf("expand("); 204 xputs(sm_debug_file(), s); 205 sm_dprintf(")\n"); 206 } 207 208 recurse = false; 209 skipping = false; 210 skiplev = 0; 211 iflev = 0; 212 quotenext = false; 213 if (s == NULL) 214 s = ""; 215 for (xp = xbuf; *s != '\0'; s++) 216 { 217 int c; 218 219 /* 220 ** Check for non-ordinary (special?) character. 221 ** 'q' will be the interpolated quantity. 222 */ 223 224 q = NULL; 225 c = *s & 0377; 226 227 if (quotenext) 228 { 229 quotenext = false; 230 goto simpleinterpolate; 231 } 232 233 switch (c) 234 { 235 case CONDIF: /* see if var set */ 236 iflev++; 237 c = *++s & 0377; 238 if (skipping) 239 skiplev++; 240 else 241 { 242 char *mv; 243 244 mv = macvalue(c, e); 245 skipping = (mv == NULL || *mv == '\0'); 246 } 247 continue; 248 249 case CONDELSE: /* change state of skipping */ 250 if (iflev == 0) 251 break; /* XXX: error */ 252 if (skiplev == 0) 253 skipping = !skipping; 254 continue; 255 256 case CONDFI: /* stop skipping */ 257 if (iflev == 0) 258 break; /* XXX: error */ 259 iflev--; 260 if (skiplev == 0) 261 skipping = false; 262 if (skipping) 263 skiplev--; 264 continue; 265 266 case MACROEXPAND: /* macro interpolation */ 267 c = bitidx(*++s); 268 if (c != '\0') 269 q = macvalue(c, e); 270 else 271 { 272 s--; 273 q = NULL; 274 } 275 if (q == NULL) 276 continue; 277 break; 278 279 case METAQUOTE: 280 /* next octet completely quoted */ 281 quotenext = true; 282 break; 283 } 284 285 /* 286 ** Interpolate q or output one character 287 */ 288 289 simpleinterpolate: 290 if (skipping || xp >= &xbuf[sizeof(xbuf) - 1]) 291 continue; 292 if (q == NULL) 293 *xp++ = c; 294 else 295 { 296 /* copy to end of q or max space remaining in buf */ 297 bool hiderecurse = false; 298 299 while ((c = *q++) != '\0' && 300 xp < &xbuf[sizeof(xbuf) - 1]) 301 { 302 /* check for any sendmail metacharacters */ 303 if (!hiderecurse && (c & 0340) == 0200) 304 recurse = true; 305 *xp++ = c; 306 307 /* give quoted characters a free ride */ 308 hiderecurse = (c & 0377) == METAQUOTE; 309 } 310 } 311 } 312 *xp = '\0'; 313 314 if (tTd(35, 28)) 315 { 316 sm_dprintf("expand(%d) ==> ", explevel); 317 xputs(sm_debug_file(), xbuf); 318 sm_dprintf("\n"); 319 } 320 321 /* recurse as appropriate */ 322 if (recurse) 323 { 324 if (explevel < MaxMacroRecursion) 325 { 326 doexpand(xbuf, buf, bufsize, explevel + 1, e); 327 return; 328 } 329 syserr("expand: recursion too deep (%d max)", 330 MaxMacroRecursion); 331 } 332 333 /* copy results out */ 334 if (explevel == 0) 335 (void) sm_strlcpy(buf, xbuf, bufsize); 336 else 337 { 338 /* leave in internal form */ 339 i = xp - xbuf; 340 if (i >= bufsize) 341 i = bufsize - 1; 342 memmove(buf, xbuf, i); 343 buf[i] = '\0'; 344 } 345 346 if (tTd(35, 24)) 347 { 348 sm_dprintf("expand ==> "); 349 xputs(sm_debug_file(), buf); 350 sm_dprintf("\n"); 351 } 352 } 353 354 void 355 expand(s, buf, bufsize, e) 356 char *s; 357 char *buf; 358 size_t bufsize; 359 ENVELOPE *e; 360 { 361 doexpand(s, buf, bufsize, 0, e); 362 } 363 364 /* 365 ** MACTABCLEAR -- clear entire macro table 366 ** 367 ** Parameters: 368 ** mac -- Macro table. 369 ** 370 ** Returns: 371 ** none. 372 ** 373 ** Side Effects: 374 ** clears entire mac structure including rpool pointer! 375 */ 376 377 void 378 mactabclear(mac) 379 MACROS_T *mac; 380 { 381 int i; 382 383 if (mac->mac_rpool == NULL) 384 { 385 for (i = 0; i < MAXMACROID; i++) 386 SM_FREE(mac->mac_table[i]); 387 } 388 memset((char *) mac, '\0', sizeof(*mac)); 389 } 390 391 /* 392 ** MACDEFINE -- bind a macro name to a value 393 ** 394 ** Set a macro to a value, with fancy storage management. 395 ** macdefine will make a copy of the value, if required, 396 ** and will ensure that the storage for the previous value 397 ** is not leaked. 398 ** 399 ** Parameters: 400 ** mac -- Macro table. 401 ** vclass -- storage class of 'value', ignored if value==NULL. 402 ** A_HEAP means that the value was allocated by 403 ** malloc, and that macdefine owns the storage. 404 ** A_TEMP means that value points to temporary storage, 405 ** and thus macdefine needs to make a copy. 406 ** A_PERM means that value points to storage that 407 ** will remain allocated and unchanged for 408 ** at least the lifetime of mac. Use A_PERM if: 409 ** -- value == NULL, 410 ** -- value points to a string literal, 411 ** -- value was allocated from mac->mac_rpool 412 ** or (in the case of an envelope macro) 413 ** from e->e_rpool, 414 ** -- in the case of an envelope macro, 415 ** value is a string member of the envelope 416 ** such as e->e_sender. 417 ** id -- Macro id. This is a single character macro name 418 ** such as 'g', or a value returned by macid(). 419 ** value -- Macro value: either NULL, or a string. 420 */ 421 422 void 423 #if SM_HEAP_CHECK 424 macdefine_tagged(mac, vclass, id, value, file, line, grp) 425 #else /* SM_HEAP_CHECK */ 426 macdefine(mac, vclass, id, value) 427 #endif /* SM_HEAP_CHECK */ 428 MACROS_T *mac; 429 ARGCLASS_T vclass; 430 int id; 431 char *value; 432 #if SM_HEAP_CHECK 433 char *file; 434 int line; 435 int grp; 436 #endif /* SM_HEAP_CHECK */ 437 { 438 char *newvalue; 439 440 if (id < 0 || id > MAXMACROID) 441 return; 442 443 if (tTd(35, 9)) 444 { 445 sm_dprintf("%sdefine(%s as ", 446 mac->mac_table[id] == NULL ? "" : "re", macname(id)); 447 xputs(sm_debug_file(), value); 448 sm_dprintf(")\n"); 449 } 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 511 void 512 macset(mac, i, value) 513 MACROS_T *mac; 514 int i; 515 char *value; 516 { 517 if (i < 0 || i > MAXMACROID) 518 return; 519 520 if (tTd(35, 9)) 521 { 522 sm_dprintf("macset(%s as ", macname(i)); 523 xputs(sm_debug_file(), value); 524 sm_dprintf(")\n"); 525 } 526 mac->mac_table[i] = value; 527 } 528 529 /* 530 ** MACVALUE -- return uninterpreted value of a macro. 531 ** 532 ** Does fancy path searching. 533 ** The low level counterpart is macget. 534 ** 535 ** Parameters: 536 ** n -- the name of the macro. 537 ** e -- envelope in which to start looking for the macro. 538 ** 539 ** Returns: 540 ** The value of n. 541 ** 542 ** Side Effects: 543 ** none. 544 */ 545 546 char * 547 macvalue(n, e) 548 int n; 549 ENVELOPE *e; 550 { 551 n = bitidx(n); 552 if (e != NULL && e->e_mci != NULL) 553 { 554 char *p = e->e_mci->mci_macro.mac_table[n]; 555 556 if (p != NULL) 557 return p; 558 } 559 while (e != NULL) 560 { 561 char *p = e->e_macro.mac_table[n]; 562 563 if (p != NULL) 564 return p; 565 if (e == e->e_parent) 566 break; 567 e = e->e_parent; 568 } 569 #if _FFR_BLANKENV_MACV 570 if (LOOKUP_MACRO_IN_BLANKENV && e != &BlankEnvelope) 571 { 572 char *p = BlankEnvelope.e_macro.mac_table[n]; 573 574 if (p != NULL) 575 return p; 576 } 577 #endif 578 return GlobalMacros.mac_table[n]; 579 } 580 581 /* 582 ** MACNAME -- return the name of a macro given its internal id 583 ** 584 ** Parameter: 585 ** n -- the id of the macro 586 ** 587 ** Returns: 588 ** The name of n. 589 ** 590 ** Side Effects: 591 ** none. 592 ** 593 ** WARNING: 594 ** Not thread-safe. 595 */ 596 597 char * 598 macname(n) 599 int n; 600 { 601 static char mbuf[2]; 602 603 n = (int)(unsigned char)n; 604 if (n > MAXMACROID) 605 return "***OUT OF RANGE MACRO***"; 606 607 /* if not ASCII printable, look up the name */ 608 if (n <= 0x20 || n > 0x7f) 609 { 610 char *p = MacroName[n]; 611 612 if (p != NULL) 613 return p; 614 return "***UNDEFINED MACRO***"; 615 } 616 617 /* if in the ASCII graphic range, just return the id directly */ 618 mbuf[0] = n; 619 mbuf[1] = '\0'; 620 return mbuf; 621 } 622 623 /* 624 ** MACID_PARSE -- return id of macro identified by its name 625 ** 626 ** Parameters: 627 ** p -- pointer to name string -- either a single 628 ** character or {name}. 629 ** ep -- filled in with the pointer to the byte 630 ** after the name. 631 ** 632 ** Returns: 633 ** 0 -- An error was detected. 634 ** 1..MAXMACROID -- The internal id code for this macro. 635 ** 636 ** Side Effects: 637 ** If this is a new macro name, a new id is allocated. 638 ** On error, syserr is called. 639 */ 640 641 int 642 macid_parse(p, ep) 643 char *p; 644 char **ep; 645 { 646 int mid; 647 char *bp; 648 char mbuf[MAXMACNAMELEN + 1]; 649 650 if (tTd(35, 14)) 651 { 652 sm_dprintf("macid("); 653 xputs(sm_debug_file(), p); 654 sm_dprintf(") => "); 655 } 656 657 if (*p == '\0' || (p[0] == '{' && p[1] == '}')) 658 { 659 syserr("Name required for macro/class"); 660 if (ep != NULL) 661 *ep = p; 662 if (tTd(35, 14)) 663 sm_dprintf("NULL\n"); 664 return 0; 665 } 666 if (*p != '{') 667 { 668 /* the macro is its own code */ 669 if (ep != NULL) 670 *ep = p + 1; 671 if (tTd(35, 14)) 672 { 673 char buf[2]; 674 675 buf[0] = *p; 676 buf[1] = '\0'; 677 xputs(sm_debug_file(), buf); 678 sm_dprintf("\n"); 679 } 680 return bitidx(*p); 681 } 682 bp = mbuf; 683 while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1]) 684 { 685 if (isascii(*p) && (isalnum(*p) || *p == '_')) 686 *bp++ = *p; 687 else 688 syserr("Invalid macro/class character %c", *p); 689 } 690 *bp = '\0'; 691 mid = -1; 692 if (*p == '\0') 693 { 694 syserr("Unbalanced { on %s", mbuf); /* missing } */ 695 } 696 else if (*p != '}') 697 { 698 syserr("Macro/class name ({%s}) too long (%d chars max)", 699 mbuf, (int) (sizeof(mbuf) - 1)); 700 } 701 else if (mbuf[1] == '\0' && mbuf[0] >= 0x20) 702 { 703 /* ${x} == $x */ 704 mid = bitidx(mbuf[0]); 705 p++; 706 } 707 else 708 { 709 STAB *s; 710 711 s = stab(mbuf, ST_MACRO, ST_ENTER); 712 if (s->s_macro != 0) 713 mid = s->s_macro; 714 else 715 { 716 if (NextMacroId > MAXMACROID) 717 { 718 syserr("Macro/class {%s}: too many long names", 719 mbuf); 720 s->s_macro = -1; 721 } 722 else 723 { 724 MacroName[NextMacroId] = s->s_name; 725 s->s_macro = mid = NextMacroId; 726 NextMacroId = NEXTMACROID(NextMacroId); 727 } 728 } 729 p++; 730 } 731 if (ep != NULL) 732 *ep = p; 733 if (mid < 0 || mid > MAXMACROID) 734 { 735 syserr("Unable to assign macro/class ID (mid = 0x%x)", mid); 736 if (tTd(35, 14)) 737 sm_dprintf("NULL\n"); 738 return 0; 739 } 740 if (tTd(35, 14)) 741 sm_dprintf("0x%x\n", mid); 742 return mid; 743 } 744 745 /* 746 ** WORDINCLASS -- tell if a word is in a specific class 747 ** 748 ** Parameters: 749 ** str -- the name of the word to look up. 750 ** cl -- the class name. 751 ** 752 ** Returns: 753 ** true if str can be found in cl. 754 ** false otherwise. 755 */ 756 757 bool 758 wordinclass(str, cl) 759 char *str; 760 int cl; 761 { 762 STAB *s; 763 764 s = stab(str, ST_CLASS, ST_FIND); 765 return s != NULL && bitnset(bitidx(cl), s->s_class); 766 } 767