1 /* 2 * Copyright (c) 1998-2001, 2003, 2006 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.102 2006/12/21 23:06:10 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 int NextMacroId = 0240; /* codes for long named macros */ 27 /* see sendmail.h: Special characters in rewriting rules. */ 28 29 30 /* 31 ** INITMACROS -- initialize the macro system 32 ** 33 ** This just involves defining some macros that are actually 34 ** used internally as metasymbols to be themselves. 35 ** 36 ** Parameters: 37 ** none. 38 ** 39 ** Returns: 40 ** none. 41 ** 42 ** Side Effects: 43 ** initializes several macros to be themselves. 44 */ 45 46 struct metamac MetaMacros[] = 47 { 48 /* LHS pattern matching characters */ 49 { '*', MATCHZANY }, { '+', MATCHANY }, { '-', MATCHONE }, 50 { '=', MATCHCLASS }, { '~', MATCHNCLASS }, 51 52 /* these are RHS metasymbols */ 53 { '#', CANONNET }, { '@', CANONHOST }, { ':', CANONUSER }, 54 { '>', CALLSUBR }, 55 56 /* the conditional operations */ 57 { '?', CONDIF }, { '|', CONDELSE }, { '.', CONDFI }, 58 59 /* the hostname lookup characters */ 60 { '[', HOSTBEGIN }, { ']', HOSTEND }, 61 { '(', LOOKUPBEGIN }, { ')', LOOKUPEND }, 62 63 /* miscellaneous control characters */ 64 { '&', MACRODEXPAND }, 65 66 { '\0', '\0' } 67 }; 68 69 #define MACBINDING(name, mid) \ 70 stab(name, ST_MACRO, ST_ENTER)->s_macro = mid; \ 71 MacroName[mid] = name; 72 73 void 74 initmacros(e) 75 ENVELOPE *e; 76 { 77 struct metamac *m; 78 int c; 79 char buf[5]; 80 81 for (m = MetaMacros; m->metaname != '\0'; m++) 82 { 83 buf[0] = m->metaval; 84 buf[1] = '\0'; 85 macdefine(&e->e_macro, A_TEMP, m->metaname, buf); 86 } 87 buf[0] = MATCHREPL; 88 buf[2] = '\0'; 89 for (c = '0'; c <= '9'; c++) 90 { 91 buf[1] = c; 92 macdefine(&e->e_macro, A_TEMP, c, buf); 93 } 94 95 /* set defaults for some macros sendmail will use later */ 96 macdefine(&e->e_macro, A_PERM, 'n', "MAILER-DAEMON"); 97 98 /* set up external names for some internal macros */ 99 MACBINDING("opMode", MID_OPMODE); 100 /*XXX should probably add equivalents for all short macros here XXX*/ 101 } 102 103 /* 104 ** EXPAND/DOEXPAND -- macro expand a string using $x escapes. 105 ** 106 ** After expansion, the expansion will be in external form (that is, 107 ** there will be no sendmail metacharacters and METAQUOTEs will have 108 ** been stripped out). 109 ** 110 ** Parameters: 111 ** s -- the string to expand. 112 ** buf -- the place to put the expansion. 113 ** bufsize -- the size of the buffer. 114 ** explevel -- the depth of expansion (doexpand only) 115 ** e -- envelope in which to work. 116 ** 117 ** Returns: 118 ** none. 119 ** 120 ** Side Effects: 121 ** none. 122 */ 123 124 static void doexpand __P(( char *, char *, size_t, int, ENVELOPE *)); 125 126 static void 127 doexpand(s, buf, bufsize, explevel, e) 128 char *s; 129 char *buf; 130 size_t bufsize; 131 int explevel; 132 ENVELOPE *e; 133 { 134 char *xp; 135 char *q; 136 bool skipping; /* set if conditionally skipping output */ 137 bool recurse; /* set if recursion required */ 138 size_t i; 139 int skiplev; /* skipping nesting level */ 140 int iflev; /* if nesting level */ 141 bool quotenext; /* quote the following character */ 142 char xbuf[MACBUFSIZE]; 143 144 if (tTd(35, 24)) 145 { 146 sm_dprintf("expand("); 147 xputs(sm_debug_file(), s); 148 sm_dprintf(")\n"); 149 } 150 151 recurse = false; 152 skipping = false; 153 skiplev = 0; 154 iflev = 0; 155 quotenext = false; 156 if (s == NULL) 157 s = ""; 158 for (xp = xbuf; *s != '\0'; s++) 159 { 160 int c; 161 162 /* 163 ** Check for non-ordinary (special?) character. 164 ** 'q' will be the interpolated quantity. 165 */ 166 167 q = NULL; 168 c = *s & 0377; 169 170 if (quotenext) 171 { 172 quotenext = false; 173 goto simpleinterpolate; 174 } 175 176 switch (c) 177 { 178 case CONDIF: /* see if var set */ 179 iflev++; 180 c = *++s & 0377; 181 if (skipping) 182 skiplev++; 183 else 184 { 185 char *mv; 186 187 mv = macvalue(c, e); 188 skipping = (mv == NULL || *mv == '\0'); 189 } 190 continue; 191 192 case CONDELSE: /* change state of skipping */ 193 if (iflev == 0) 194 break; /* XXX: error */ 195 if (skiplev == 0) 196 skipping = !skipping; 197 continue; 198 199 case CONDFI: /* stop skipping */ 200 if (iflev == 0) 201 break; /* XXX: error */ 202 iflev--; 203 if (skiplev == 0) 204 skipping = false; 205 if (skipping) 206 skiplev--; 207 continue; 208 209 case MACROEXPAND: /* macro interpolation */ 210 c = bitidx(*++s); 211 if (c != '\0') 212 q = macvalue(c, e); 213 else 214 { 215 s--; 216 q = NULL; 217 } 218 if (q == NULL) 219 continue; 220 break; 221 222 case METAQUOTE: 223 /* next octet completely quoted */ 224 quotenext = true; 225 break; 226 } 227 228 /* 229 ** Interpolate q or output one character 230 */ 231 232 simpleinterpolate: 233 if (skipping || xp >= &xbuf[sizeof(xbuf) - 1]) 234 continue; 235 if (q == NULL) 236 *xp++ = c; 237 else 238 { 239 /* copy to end of q or max space remaining in buf */ 240 bool hiderecurse = false; 241 242 while ((c = *q++) != '\0' && 243 xp < &xbuf[sizeof(xbuf) - 1]) 244 { 245 /* check for any sendmail metacharacters */ 246 if (!hiderecurse && (c & 0340) == 0200) 247 recurse = true; 248 *xp++ = c; 249 250 /* give quoted characters a free ride */ 251 hiderecurse = (c & 0377) == METAQUOTE; 252 } 253 } 254 } 255 *xp = '\0'; 256 257 if (tTd(35, 28)) 258 { 259 sm_dprintf("expand(%d) ==> ", explevel); 260 xputs(sm_debug_file(), xbuf); 261 sm_dprintf("\n"); 262 } 263 264 /* recurse as appropriate */ 265 if (recurse) 266 { 267 if (explevel < MaxMacroRecursion) 268 { 269 doexpand(xbuf, buf, bufsize, explevel + 1, e); 270 return; 271 } 272 syserr("expand: recursion too deep (%d max)", 273 MaxMacroRecursion); 274 } 275 276 /* copy results out */ 277 if (explevel == 0) 278 (void) sm_strlcpy(buf, xbuf, bufsize); 279 else 280 { 281 /* leave in internal form */ 282 i = xp - xbuf; 283 if (i >= bufsize) 284 i = bufsize - 1; 285 memmove(buf, xbuf, i); 286 buf[i] = '\0'; 287 } 288 289 if (tTd(35, 24)) 290 { 291 sm_dprintf("expand ==> "); 292 xputs(sm_debug_file(), buf); 293 sm_dprintf("\n"); 294 } 295 } 296 297 void 298 expand(s, buf, bufsize, e) 299 char *s; 300 char *buf; 301 size_t bufsize; 302 ENVELOPE *e; 303 { 304 doexpand(s, buf, bufsize, 0, e); 305 } 306 307 /* 308 ** MACDEFINE -- bind a macro name to a value 309 ** 310 ** Set a macro to a value, with fancy storage management. 311 ** macdefine will make a copy of the value, if required, 312 ** and will ensure that the storage for the previous value 313 ** is not leaked. 314 ** 315 ** Parameters: 316 ** mac -- Macro table. 317 ** vclass -- storage class of 'value', ignored if value==NULL. 318 ** A_HEAP means that the value was allocated by 319 ** malloc, and that macdefine owns the storage. 320 ** A_TEMP means that value points to temporary storage, 321 ** and thus macdefine needs to make a copy. 322 ** A_PERM means that value points to storage that 323 ** will remain allocated and unchanged for 324 ** at least the lifetime of mac. Use A_PERM if: 325 ** -- value == NULL, 326 ** -- value points to a string literal, 327 ** -- value was allocated from mac->mac_rpool 328 ** or (in the case of an envelope macro) 329 ** from e->e_rpool, 330 ** -- in the case of an envelope macro, 331 ** value is a string member of the envelope 332 ** such as e->e_sender. 333 ** id -- Macro id. This is a single character macro name 334 ** such as 'g', or a value returned by macid(). 335 ** value -- Macro value: either NULL, or a string. 336 */ 337 338 void 339 #if SM_HEAP_CHECK 340 macdefine_tagged(mac, vclass, id, value, file, line, grp) 341 #else /* SM_HEAP_CHECK */ 342 macdefine(mac, vclass, id, value) 343 #endif /* SM_HEAP_CHECK */ 344 MACROS_T *mac; 345 ARGCLASS_T vclass; 346 int id; 347 char *value; 348 #if SM_HEAP_CHECK 349 char *file; 350 int line; 351 int grp; 352 #endif /* SM_HEAP_CHECK */ 353 { 354 char *newvalue; 355 356 if (id < 0 || id > MAXMACROID) 357 return; 358 359 if (tTd(35, 9)) 360 { 361 sm_dprintf("%sdefine(%s as ", 362 mac->mac_table[id] == NULL ? "" : "re", macname(id)); 363 xputs(sm_debug_file(), value); 364 sm_dprintf(")\n"); 365 } 366 367 if (mac->mac_rpool == NULL) 368 { 369 char *freeit = NULL; 370 371 if (mac->mac_table[id] != NULL && 372 bitnset(id, mac->mac_allocated)) 373 freeit = mac->mac_table[id]; 374 375 if (value == NULL || vclass == A_HEAP) 376 { 377 sm_heap_checkptr_tagged(value, file, line); 378 newvalue = value; 379 clrbitn(id, mac->mac_allocated); 380 } 381 else 382 { 383 #if SM_HEAP_CHECK 384 newvalue = sm_strdup_tagged_x(value, file, line, 0); 385 #else /* SM_HEAP_CHECK */ 386 newvalue = sm_strdup_x(value); 387 #endif /* SM_HEAP_CHECK */ 388 setbitn(id, mac->mac_allocated); 389 } 390 mac->mac_table[id] = newvalue; 391 if (freeit != NULL) 392 sm_free(freeit); 393 } 394 else 395 { 396 if (value == NULL || vclass == A_PERM) 397 newvalue = value; 398 else 399 newvalue = sm_rpool_strdup_x(mac->mac_rpool, value); 400 mac->mac_table[id] = newvalue; 401 if (vclass == A_HEAP) 402 sm_free(value); 403 } 404 405 #if _FFR_RESET_MACRO_GLOBALS 406 switch (id) 407 { 408 case 'j': 409 PSTRSET(MyHostName, value); 410 break; 411 } 412 #endif /* _FFR_RESET_MACRO_GLOBALS */ 413 } 414 415 /* 416 ** MACSET -- set a named macro to a value (low level) 417 ** 418 ** No fancy storage management; the caller takes full responsibility. 419 ** Often used with macget; see also macdefine. 420 ** 421 ** Parameters: 422 ** mac -- Macro table. 423 ** i -- Macro name, specified as an integer offset. 424 ** value -- Macro value: either NULL, or a string. 425 */ 426 427 void 428 macset(mac, i, value) 429 MACROS_T *mac; 430 int i; 431 char *value; 432 { 433 if (i < 0 || i > MAXMACROID) 434 return; 435 436 if (tTd(35, 9)) 437 { 438 sm_dprintf("macset(%s as ", macname(i)); 439 xputs(sm_debug_file(), value); 440 sm_dprintf(")\n"); 441 } 442 mac->mac_table[i] = value; 443 } 444 445 /* 446 ** MACVALUE -- return uninterpreted value of a macro. 447 ** 448 ** Does fancy path searching. 449 ** The low level counterpart is macget. 450 ** 451 ** Parameters: 452 ** n -- the name of the macro. 453 ** e -- envelope in which to start looking for the macro. 454 ** 455 ** Returns: 456 ** The value of n. 457 ** 458 ** Side Effects: 459 ** none. 460 */ 461 462 char * 463 macvalue(n, e) 464 int n; 465 ENVELOPE *e; 466 { 467 n = bitidx(n); 468 if (e != NULL && e->e_mci != NULL) 469 { 470 char *p = e->e_mci->mci_macro.mac_table[n]; 471 472 if (p != NULL) 473 return p; 474 } 475 while (e != NULL) 476 { 477 char *p = e->e_macro.mac_table[n]; 478 479 if (p != NULL) 480 return p; 481 if (e == e->e_parent) 482 break; 483 e = e->e_parent; 484 } 485 return GlobalMacros.mac_table[n]; 486 } 487 488 /* 489 ** MACNAME -- return the name of a macro given its internal id 490 ** 491 ** Parameter: 492 ** n -- the id of the macro 493 ** 494 ** Returns: 495 ** The name of n. 496 ** 497 ** Side Effects: 498 ** none. 499 ** 500 ** WARNING: 501 ** Not thread-safe. 502 */ 503 504 char * 505 macname(n) 506 int n; 507 { 508 static char mbuf[2]; 509 510 n = (int)(unsigned char)n; 511 if (n > MAXMACROID) 512 return "***OUT OF RANGE MACRO***"; 513 514 /* if not ASCII printable, look up the name */ 515 if (n <= 0x20 || n > 0x7f) 516 { 517 char *p = MacroName[n]; 518 519 if (p != NULL) 520 return p; 521 return "***UNDEFINED MACRO***"; 522 } 523 524 /* if in the ASCII graphic range, just return the id directly */ 525 mbuf[0] = n; 526 mbuf[1] = '\0'; 527 return mbuf; 528 } 529 530 /* 531 ** MACID_PARSE -- return id of macro identified by its name 532 ** 533 ** Parameters: 534 ** p -- pointer to name string -- either a single 535 ** character or {name}. 536 ** ep -- filled in with the pointer to the byte 537 ** after the name. 538 ** 539 ** Returns: 540 ** 0 -- An error was detected. 541 ** 1..MAXMACROID -- The internal id code for this macro. 542 ** 543 ** Side Effects: 544 ** If this is a new macro name, a new id is allocated. 545 ** On error, syserr is called. 546 */ 547 548 int 549 macid_parse(p, ep) 550 char *p; 551 char **ep; 552 { 553 int mid; 554 char *bp; 555 char mbuf[MAXMACNAMELEN + 1]; 556 557 if (tTd(35, 14)) 558 { 559 sm_dprintf("macid("); 560 xputs(sm_debug_file(), p); 561 sm_dprintf(") => "); 562 } 563 564 if (*p == '\0' || (p[0] == '{' && p[1] == '}')) 565 { 566 syserr("Name required for macro/class"); 567 if (ep != NULL) 568 *ep = p; 569 if (tTd(35, 14)) 570 sm_dprintf("NULL\n"); 571 return 0; 572 } 573 if (*p != '{') 574 { 575 /* the macro is its own code */ 576 if (ep != NULL) 577 *ep = p + 1; 578 if (tTd(35, 14)) 579 { 580 char buf[2]; 581 582 buf[0] = *p; 583 buf[1] = '\0'; 584 xputs(sm_debug_file(), buf); 585 sm_dprintf("\n"); 586 } 587 return bitidx(*p); 588 } 589 bp = mbuf; 590 while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof(mbuf) - 1]) 591 { 592 if (isascii(*p) && (isalnum(*p) || *p == '_')) 593 *bp++ = *p; 594 else 595 syserr("Invalid macro/class character %c", *p); 596 } 597 *bp = '\0'; 598 mid = -1; 599 if (*p == '\0') 600 { 601 syserr("Unbalanced { on %s", mbuf); /* missing } */ 602 } 603 else if (*p != '}') 604 { 605 syserr("Macro/class name ({%s}) too long (%d chars max)", 606 mbuf, (int) (sizeof(mbuf) - 1)); 607 } 608 else if (mbuf[1] == '\0') 609 { 610 /* ${x} == $x */ 611 mid = bitidx(mbuf[0]); 612 p++; 613 } 614 else 615 { 616 STAB *s; 617 618 s = stab(mbuf, ST_MACRO, ST_ENTER); 619 if (s->s_macro != 0) 620 mid = s->s_macro; 621 else 622 { 623 if (NextMacroId > MAXMACROID) 624 { 625 syserr("Macro/class {%s}: too many long names", 626 mbuf); 627 s->s_macro = -1; 628 } 629 else 630 { 631 MacroName[NextMacroId] = s->s_name; 632 s->s_macro = mid = NextMacroId++; 633 } 634 } 635 p++; 636 } 637 if (ep != NULL) 638 *ep = p; 639 if (mid < 0 || mid > MAXMACROID) 640 { 641 syserr("Unable to assign macro/class ID (mid = 0x%x)", mid); 642 if (tTd(35, 14)) 643 sm_dprintf("NULL\n"); 644 return 0; 645 } 646 if (tTd(35, 14)) 647 sm_dprintf("0x%x\n", mid); 648 return mid; 649 } 650 651 /* 652 ** WORDINCLASS -- tell if a word is in a specific class 653 ** 654 ** Parameters: 655 ** str -- the name of the word to look up. 656 ** cl -- the class name. 657 ** 658 ** Returns: 659 ** true if str can be found in cl. 660 ** false otherwise. 661 */ 662 663 bool 664 wordinclass(str, cl) 665 char *str; 666 int cl; 667 { 668 STAB *s; 669 670 s = stab(str, ST_CLASS, ST_FIND); 671 return s != NULL && bitnset(bitidx(cl), s->s_class); 672 } 673