1 /* 2 * Copyright (c) 1998-2001 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 #include <sendmail.h> 15 16 17 #ifndef lint 18 # ifdef DAEMON 19 static char id[] = "@(#)$Id: daemon.c,v 8.401.4.51 2001/02/23 18:57:27 geir Exp $ (with daemon mode)"; 20 # else /* DAEMON */ 21 static char id[] = "@(#)$Id: daemon.c,v 8.401.4.51 2001/02/23 18:57:27 geir Exp $ (without daemon mode)"; 22 # endif /* DAEMON */ 23 #endif /* ! lint */ 24 25 #if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__) 26 # define USE_SOCK_STREAM 1 27 #endif /* defined(SOCK_STREAM) || defined(__GNU_LIBRARY__) */ 28 29 #if DAEMON || defined(USE_SOCK_STREAM) 30 # if NETINET || NETINET6 31 # include <arpa/inet.h> 32 # endif /* NETINET || NETINET6 */ 33 # if NAMED_BIND 34 # ifndef NO_DATA 35 # define NO_DATA NO_ADDRESS 36 # endif /* ! NO_DATA */ 37 # endif /* NAMED_BIND */ 38 #endif /* DAEMON || defined(USE_SOCK_STREAM) */ 39 40 #if DAEMON 41 42 # if STARTTLS 43 # include <openssl/rand.h> 44 # endif /* STARTTLS */ 45 46 # include <sys/time.h> 47 48 # if IP_SRCROUTE && NETINET 49 # include <netinet/in_systm.h> 50 # include <netinet/ip.h> 51 # if HAS_IN_H 52 # include <netinet/in.h> 53 # ifndef IPOPTION 54 # define IPOPTION ip_opts 55 # define IP_LIST ip_opts 56 # define IP_DST ip_dst 57 # endif /* ! IPOPTION */ 58 # else /* HAS_IN_H */ 59 # include <netinet/ip_var.h> 60 # ifndef IPOPTION 61 # define IPOPTION ipoption 62 # define IP_LIST ipopt_list 63 # define IP_DST ipopt_dst 64 # endif /* ! IPOPTION */ 65 # endif /* HAS_IN_H */ 66 # endif /* IP_SRCROUTE && NETINET */ 67 68 /* structure to describe a daemon */ 69 struct daemon 70 { 71 int d_socket; /* fd for socket */ 72 SOCKADDR d_addr; /* socket for incoming */ 73 u_short d_port; /* port number */ 74 int d_listenqueue; /* size of listen queue */ 75 int d_tcprcvbufsize; /* size of TCP receive buffer */ 76 int d_tcpsndbufsize; /* size of TCP send buffer */ 77 time_t d_refuse_connections_until; 78 bool d_firsttime; 79 int d_socksize; 80 BITMAP256 d_flags; /* flags; see sendmail.h */ 81 char *d_mflags; /* flags for use in macro */ 82 char *d_name; /* user-supplied name */ 83 }; 84 85 typedef struct daemon DAEMON_T; 86 87 static void connecttimeout __P((void)); 88 static int opendaemonsocket __P((struct daemon *, bool)); 89 static u_short setupdaemon __P((SOCKADDR *)); 90 91 /* 92 ** DAEMON.C -- routines to use when running as a daemon. 93 ** 94 ** This entire file is highly dependent on the 4.2 BSD 95 ** interprocess communication primitives. No attempt has 96 ** been made to make this file portable to Version 7, 97 ** Version 6, MPX files, etc. If you should try such a 98 ** thing yourself, I recommend chucking the entire file 99 ** and starting from scratch. Basic semantics are: 100 ** 101 ** getrequests(e) 102 ** Opens a port and initiates a connection. 103 ** Returns in a child. Must set InChannel and 104 ** OutChannel appropriately. 105 ** clrdaemon() 106 ** Close any open files associated with getting 107 ** the connection; this is used when running the queue, 108 ** etc., to avoid having extra file descriptors during 109 ** the queue run and to avoid confusing the network 110 ** code (if it cares). 111 ** makeconnection(host, port, outfile, infile, e) 112 ** Make a connection to the named host on the given 113 ** port. Set *outfile and *infile to the files 114 ** appropriate for communication. Returns zero on 115 ** success, else an exit status describing the 116 ** error. 117 ** host_map_lookup(map, hbuf, avp, pstat) 118 ** Convert the entry in hbuf into a canonical form. 119 */ 120 121 static DAEMON_T Daemons[MAXDAEMONS]; 122 static int ndaemons = 0; /* actual number of daemons */ 123 124 /* options for client */ 125 static int TcpRcvBufferSize = 0; /* size of TCP receive buffer */ 126 static int TcpSndBufferSize = 0; /* size of TCP send buffer */ 127 128 /* 129 ** GETREQUESTS -- open mail IPC port and get requests. 130 ** 131 ** Parameters: 132 ** e -- the current envelope. 133 ** 134 ** Returns: 135 ** pointer to flags. 136 ** 137 ** Side Effects: 138 ** Waits until some interesting activity occurs. When 139 ** it does, a child is created to process it, and the 140 ** parent waits for completion. Return from this 141 ** routine is always in the child. The file pointers 142 ** "InChannel" and "OutChannel" should be set to point 143 ** to the communication channel. 144 */ 145 146 BITMAP256 * 147 getrequests(e) 148 ENVELOPE *e; 149 { 150 int t; 151 time_t last_disk_space_check = 0; 152 int idx, curdaemon = -1; 153 int i, olddaemon = 0; 154 # if XDEBUG 155 bool j_has_dot; 156 # endif /* XDEBUG */ 157 char status[MAXLINE]; 158 SOCKADDR sa; 159 SOCKADDR_LEN_T len = sizeof sa; 160 # if NETUNIX 161 extern int ControlSocket; 162 # endif /* NETUNIX */ 163 extern ENVELOPE BlankEnvelope; 164 165 166 for (idx = 0; idx < ndaemons; idx++) 167 { 168 Daemons[idx].d_port = setupdaemon(&(Daemons[idx].d_addr)); 169 Daemons[idx].d_firsttime = TRUE; 170 Daemons[idx].d_refuse_connections_until = (time_t) 0; 171 } 172 173 /* 174 ** Try to actually open the connection. 175 */ 176 177 if (tTd(15, 1)) 178 { 179 for (idx = 0; idx < ndaemons; idx++) 180 { 181 dprintf("getrequests: daemon %s: port %d\n", 182 Daemons[idx].d_name, 183 ntohs(Daemons[idx].d_port)); 184 } 185 } 186 187 /* get a socket for the SMTP connection */ 188 for (idx = 0; idx < ndaemons; idx++) 189 Daemons[idx].d_socksize = opendaemonsocket(&Daemons[idx], TRUE); 190 191 if (opencontrolsocket() < 0) 192 sm_syslog(LOG_WARNING, NOQID, 193 "daemon could not open control socket %s: %s", 194 ControlSocketName, errstring(errno)); 195 196 (void) setsignal(SIGCHLD, reapchild); 197 198 /* write the pid to file */ 199 log_sendmail_pid(e); 200 201 # if XDEBUG 202 { 203 char jbuf[MAXHOSTNAMELEN]; 204 205 expand("\201j", jbuf, sizeof jbuf, e); 206 j_has_dot = strchr(jbuf, '.') != NULL; 207 } 208 # endif /* XDEBUG */ 209 210 /* Add parent process as first item */ 211 proc_list_add(getpid(), "Sendmail daemon", PROC_DAEMON); 212 213 if (tTd(15, 1)) 214 { 215 for (idx = 0; idx < ndaemons; idx++) 216 dprintf("getrequests: daemon %s: %d\n", 217 Daemons[idx].d_name, 218 Daemons[idx].d_socket); 219 } 220 221 for (;;) 222 { 223 register pid_t pid; 224 auto SOCKADDR_LEN_T lotherend; 225 bool timedout = FALSE; 226 bool control = FALSE; 227 int save_errno; 228 int pipefd[2]; 229 time_t timenow; 230 # if STARTTLS 231 long seed; 232 # endif /* STARTTLS */ 233 extern bool refuseconnections __P((char *, ENVELOPE *, int)); 234 235 /* see if we are rejecting connections */ 236 (void) blocksignal(SIGALRM); 237 238 timenow = curtime(); 239 240 /* 241 ** Use ConnRateThrottle only if the 242 ** last pass was for a connection 243 */ 244 245 if (ConnRateThrottle > 0 && curdaemon >= 0) 246 { 247 static int conncnt = 0; 248 static time_t lastconn = 0; 249 250 if (timenow != lastconn) 251 { 252 lastconn = timenow; 253 conncnt = 1; 254 } 255 else if (++conncnt > ConnRateThrottle) 256 { 257 /* sleep to flatten out connection load */ 258 sm_setproctitle(TRUE, e, 259 "deferring connections: %d per second", 260 ConnRateThrottle); 261 if (LogLevel >= 9) 262 sm_syslog(LOG_INFO, NOQID, 263 "deferring connections: %d per second", 264 ConnRateThrottle); 265 (void) sleep(1); 266 } 267 } 268 269 for (idx = 0; idx < ndaemons; idx++) 270 { 271 if (timenow < Daemons[idx].d_refuse_connections_until) 272 continue; 273 if (refuseconnections(Daemons[idx].d_name, e, idx)) 274 { 275 if (Daemons[idx].d_socket >= 0) 276 { 277 /* close socket so peer fails quickly */ 278 (void) close(Daemons[idx].d_socket); 279 Daemons[idx].d_socket = -1; 280 } 281 282 /* refuse connections for next 15 seconds */ 283 Daemons[idx].d_refuse_connections_until = timenow + 15; 284 } 285 else if (Daemons[idx].d_socket < 0 || 286 Daemons[idx].d_firsttime) 287 { 288 if (!Daemons[idx].d_firsttime && LogLevel >= 9) 289 sm_syslog(LOG_INFO, NOQID, 290 "accepting connections again for daemon %s", 291 Daemons[idx].d_name); 292 293 /* arrange to (re)open the socket if needed */ 294 (void) opendaemonsocket(&Daemons[idx], FALSE); 295 Daemons[idx].d_firsttime = FALSE; 296 } 297 } 298 299 if (timenow >= last_disk_space_check) 300 { 301 bool logged = FALSE; 302 303 if (!enoughdiskspace(MinBlocksFree + 1, FALSE)) 304 { 305 for (idx = 0; idx < ndaemons; idx++) 306 { 307 if (!bitnset(D_ETRNONLY, Daemons[idx].d_flags)) 308 { 309 /* log only if not logged before */ 310 if (!logged) 311 { 312 if (LogLevel >= 9) 313 sm_syslog(LOG_INFO, NOQID, 314 "rejecting new messages: min free: %ld", 315 MinBlocksFree); 316 logged = TRUE; 317 sm_setproctitle(TRUE, e, 318 "rejecting new messages: min free: %ld", 319 MinBlocksFree); 320 } 321 setbitn(D_ETRNONLY, Daemons[idx].d_flags); 322 } 323 } 324 } 325 else 326 { 327 for (idx = 0; idx < ndaemons; idx++) 328 { 329 if (bitnset(D_ETRNONLY, Daemons[idx].d_flags)) 330 { 331 /* log only if not logged before */ 332 if (!logged) 333 { 334 if (LogLevel >= 9) 335 sm_syslog(LOG_INFO, NOQID, 336 "accepting new messages (again)"); 337 logged = TRUE; 338 } 339 340 /* title will be set below */ 341 clrbitn(D_ETRNONLY, Daemons[idx].d_flags); 342 } 343 } 344 } 345 /* only check disk space once a minute */ 346 last_disk_space_check = timenow + 60; 347 } 348 349 # if XDEBUG 350 /* check for disaster */ 351 { 352 char jbuf[MAXHOSTNAMELEN]; 353 354 expand("\201j", jbuf, sizeof jbuf, e); 355 if (!wordinclass(jbuf, 'w')) 356 { 357 dumpstate("daemon lost $j"); 358 sm_syslog(LOG_ALERT, NOQID, 359 "daemon process doesn't have $j in $=w; see syslog"); 360 abort(); 361 } 362 else if (j_has_dot && strchr(jbuf, '.') == NULL) 363 { 364 dumpstate("daemon $j lost dot"); 365 sm_syslog(LOG_ALERT, NOQID, 366 "daemon process $j lost dot; see syslog"); 367 abort(); 368 } 369 } 370 # endif /* XDEBUG */ 371 372 # if 0 373 /* 374 ** Andrew Sun <asun@ieps-sun.ml.com> claims that this will 375 ** fix the SVr4 problem. But it seems to have gone away, 376 ** so is it worth doing this? 377 */ 378 379 if (DaemonSocket >= 0 && 380 SetNonBlocking(DaemonSocket, FALSE) < 0) 381 log an error here; 382 # endif /* 0 */ 383 (void) releasesignal(SIGALRM); 384 385 for (;;) 386 { 387 bool setproc = FALSE; 388 int highest = -1; 389 fd_set readfds; 390 struct timeval timeout; 391 392 FD_ZERO(&readfds); 393 394 for (idx = 0; idx < ndaemons; idx++) 395 { 396 /* wait for a connection */ 397 if (Daemons[idx].d_socket >= 0) 398 { 399 if (!setproc && 400 !bitnset(D_ETRNONLY, 401 Daemons[idx].d_flags)) 402 { 403 sm_setproctitle(TRUE, e, 404 "accepting connections"); 405 setproc = TRUE; 406 } 407 if (Daemons[idx].d_socket > highest) 408 highest = Daemons[idx].d_socket; 409 FD_SET((u_int)Daemons[idx].d_socket, &readfds); 410 } 411 } 412 413 # if NETUNIX 414 if (ControlSocket >= 0) 415 { 416 if (ControlSocket > highest) 417 highest = ControlSocket; 418 FD_SET(ControlSocket, &readfds); 419 } 420 # endif /* NETUNIX */ 421 422 /* 423 ** if one socket is closed, set the timeout 424 ** to 5 seconds (so it might get reopened soon), 425 ** otherwise (all sockets open) 60. 426 */ 427 428 idx = 0; 429 while (idx < ndaemons && Daemons[idx].d_socket >= 0) 430 idx++; 431 if (idx < ndaemons) 432 timeout.tv_sec = 5; 433 else 434 timeout.tv_sec = 60; 435 timeout.tv_usec = 0; 436 437 t = select(highest + 1, FDSET_CAST &readfds, 438 NULL, NULL, &timeout); 439 440 441 442 if (DoQueueRun) 443 (void) runqueue(TRUE, FALSE); 444 445 curdaemon = -1; 446 if (t <= 0) 447 { 448 timedout = TRUE; 449 break; 450 } 451 452 control = FALSE; 453 errno = 0; 454 455 /* look "round-robin" for an active socket */ 456 if ((idx = olddaemon + 1) >= ndaemons) 457 idx = 0; 458 for (i = 0; i < ndaemons; i++) 459 { 460 if (Daemons[idx].d_socket >= 0 && 461 FD_ISSET(Daemons[idx].d_socket, &readfds)) 462 { 463 lotherend = Daemons[idx].d_socksize; 464 memset(&RealHostAddr, '\0', 465 sizeof RealHostAddr); 466 t = accept(Daemons[idx].d_socket, 467 (struct sockaddr *)&RealHostAddr, 468 &lotherend); 469 470 /* 471 ** If remote side closes before 472 ** accept() finishes, sockaddr 473 ** might not be fully filled in. 474 */ 475 476 if (t >= 0 && 477 (lotherend == 0 || 478 # ifdef BSD4_4_SOCKADDR 479 RealHostAddr.sa.sa_len == 0 || 480 # endif /* BSD4_4_SOCKADDR */ 481 RealHostAddr.sa.sa_family != Daemons[idx].d_addr.sa.sa_family)) 482 { 483 (void) close(t); 484 t = -1; 485 errno = EINVAL; 486 } 487 olddaemon = curdaemon = idx; 488 break; 489 } 490 if (++idx >= ndaemons) 491 idx = 0; 492 } 493 # if NETUNIX 494 if (curdaemon == -1 && ControlSocket >= 0 && 495 FD_ISSET(ControlSocket, &readfds)) 496 { 497 struct sockaddr_un sa_un; 498 499 lotherend = sizeof sa_un; 500 memset(&sa_un, '\0', sizeof sa_un); 501 t = accept(ControlSocket, 502 (struct sockaddr *)&sa_un, 503 &lotherend); 504 505 /* 506 ** If remote side closes before 507 ** accept() finishes, sockaddr 508 ** might not be fully filled in. 509 */ 510 511 if (t >= 0 && 512 (lotherend == 0 || 513 # ifdef BSD4_4_SOCKADDR 514 sa_un.sun_len == 0 || 515 # endif /* BSD4_4_SOCKADDR */ 516 sa_un.sun_family != AF_UNIX)) 517 { 518 (void) close(t); 519 t = -1; 520 errno = EINVAL; 521 } 522 if (t >= 0) 523 control = TRUE; 524 } 525 # else /* NETUNIX */ 526 if (curdaemon == -1) 527 { 528 /* No daemon to service */ 529 continue; 530 } 531 # endif /* NETUNIX */ 532 if (t >= 0 || errno != EINTR) 533 break; 534 } 535 if (timedout) 536 { 537 timedout = FALSE; 538 continue; 539 } 540 save_errno = errno; 541 timenow = curtime(); 542 (void) blocksignal(SIGALRM); 543 if (t < 0) 544 { 545 errno = save_errno; 546 syserr("getrequests: accept"); 547 548 /* arrange to re-open the socket next time around */ 549 (void) close(Daemons[curdaemon].d_socket); 550 Daemons[curdaemon].d_socket = -1; 551 # if SO_REUSEADDR_IS_BROKEN 552 /* 553 ** Give time for bound socket to be released. 554 ** This creates a denial-of-service if you can 555 ** force accept() to fail on affected systems. 556 */ 557 558 Daemons[curdaemon].d_refuse_connections_until = timenow + 15; 559 # endif /* SO_REUSEADDR_IS_BROKEN */ 560 continue; 561 } 562 563 if (!control) 564 { 565 /* set some daemon related macros */ 566 switch (Daemons[curdaemon].d_addr.sa.sa_family) 567 { 568 case AF_UNSPEC: 569 define(macid("{daemon_family}", NULL), 570 "unspec", &BlankEnvelope); 571 break; 572 # if NETINET 573 case AF_INET: 574 define(macid("{daemon_family}", NULL), 575 "inet", &BlankEnvelope); 576 break; 577 # endif /* NETINET */ 578 # if NETINET6 579 case AF_INET6: 580 define(macid("{daemon_family}", NULL), 581 "inet6", &BlankEnvelope); 582 break; 583 # endif /* NETINET6 */ 584 # if NETISO 585 case AF_ISO: 586 define(macid("{daemon_family}", NULL), 587 "iso", &BlankEnvelope); 588 break; 589 # endif /* NETISO */ 590 # if NETNS 591 case AF_NS: 592 define(macid("{daemon_family}", NULL), 593 "ns", &BlankEnvelope); 594 break; 595 # endif /* NETNS */ 596 # if NETX25 597 case AF_CCITT: 598 define(macid("{daemon_family}", NULL), 599 "x.25", &BlankEnvelope); 600 break; 601 # endif /* NETX25 */ 602 } 603 define(macid("{daemon_name}", NULL), 604 Daemons[curdaemon].d_name, &BlankEnvelope); 605 if (Daemons[curdaemon].d_mflags != NULL) 606 define(macid("{daemon_flags}", NULL), 607 Daemons[curdaemon].d_mflags, 608 &BlankEnvelope); 609 else 610 define(macid("{daemon_flags}", NULL), 611 "", &BlankEnvelope); 612 } 613 614 /* 615 ** Create a subprocess to process the mail. 616 */ 617 618 if (tTd(15, 2)) 619 dprintf("getrequests: forking (fd = %d)\n", t); 620 621 /* 622 ** advance state of PRNG 623 ** this is necessary because otherwise all child processes 624 ** will produce the same PRN sequence and hence the selection 625 ** of a queue directory (and other things, e.g., MX selection) 626 ** are not "really" random. 627 */ 628 # if STARTTLS 629 seed = get_random(); 630 RAND_seed((void *) &last_disk_space_check, 631 sizeof last_disk_space_check); 632 RAND_seed((void *) &timenow, sizeof timenow); 633 RAND_seed((void *) &seed, sizeof seed); 634 # else /* STARTTLS */ 635 (void) get_random(); 636 # endif /* STARTTLS */ 637 638 #ifndef DEBUG_NO_FORK 639 /* 640 ** Create a pipe to keep the child from writing to the 641 ** socket until after the parent has closed it. Otherwise 642 ** the parent may hang if the child has closed it first. 643 */ 644 645 if (pipe(pipefd) < 0) 646 pipefd[0] = pipefd[1] = -1; 647 648 (void) blocksignal(SIGCHLD); 649 pid = fork(); 650 if (pid < 0) 651 { 652 syserr("daemon: cannot fork"); 653 if (pipefd[0] != -1) 654 { 655 (void) close(pipefd[0]); 656 (void) close(pipefd[1]); 657 } 658 (void) releasesignal(SIGCHLD); 659 (void) sleep(10); 660 (void) close(t); 661 continue; 662 } 663 #else /* ! DEBUG_NO_FORK */ 664 pid = 0; 665 #endif /* ! DEBUG_NO_FORK */ 666 667 if (pid == 0) 668 { 669 char *p; 670 FILE *inchannel, *outchannel = NULL; 671 672 /* 673 ** CHILD -- return to caller. 674 ** Collect verified idea of sending host. 675 ** Verify calling user id if possible here. 676 */ 677 678 if (!control) 679 { 680 define(macid("{daemon_addr}", NULL), 681 newstr(anynet_ntoa(&Daemons[curdaemon].d_addr)), 682 &BlankEnvelope); 683 (void) snprintf(status, sizeof status, "%d", 684 ntohs(Daemons[curdaemon].d_port)); 685 define(macid("{daemon_port}", NULL), 686 newstr(status), &BlankEnvelope); 687 } 688 689 (void) releasesignal(SIGALRM); 690 (void) releasesignal(SIGCHLD); 691 (void) setsignal(SIGCHLD, SIG_DFL); 692 (void) setsignal(SIGHUP, intsig); 693 for (idx = 0; idx < ndaemons; idx++) 694 { 695 if (Daemons[idx].d_socket >= 0) 696 (void) close(Daemons[idx].d_socket); 697 } 698 clrcontrol(); 699 700 /* Avoid SMTP daemon actions if control command */ 701 if (control) 702 { 703 /* Add control socket process */ 704 proc_list_add(getpid(), "console socket child", 705 PROC_CONTROL_CHILD); 706 } 707 else 708 { 709 proc_list_clear(); 710 711 /* Add parent process as first child item */ 712 proc_list_add(getpid(), "daemon child", 713 PROC_DAEMON_CHILD); 714 715 /* don't schedule queue runs if ETRN */ 716 QueueIntvl = 0; 717 718 sm_setproctitle(TRUE, e, "startup with %s", 719 anynet_ntoa(&RealHostAddr)); 720 } 721 722 #ifndef DEBUG_NO_FORK 723 if (pipefd[0] != -1) 724 { 725 auto char c; 726 727 /* 728 ** Wait for the parent to close the write end 729 ** of the pipe, which we will see as an EOF. 730 ** This guarantees that we won't write to the 731 ** socket until after the parent has closed 732 ** the pipe. 733 */ 734 735 /* close the write end of the pipe */ 736 (void) close(pipefd[1]); 737 738 /* we shouldn't be interrupted, but ... */ 739 while (read(pipefd[0], &c, 1) < 0 && 740 errno == EINTR) 741 continue; 742 (void) close(pipefd[0]); 743 } 744 #endif /* ! DEBUG_NO_FORK */ 745 746 /* control socket processing */ 747 if (control) 748 { 749 control_command(t, e); 750 751 /* NOTREACHED */ 752 exit(EX_SOFTWARE); 753 } 754 755 /* determine host name */ 756 p = hostnamebyanyaddr(&RealHostAddr); 757 if (strlen(p) > (SIZE_T) MAXNAME) 758 p[MAXNAME] = '\0'; 759 RealHostName = newstr(p); 760 if (RealHostName[0] == '[') 761 { 762 /* TEMP, FAIL: which one? */ 763 define(macid("{client_resolve}", NULL), 764 (h_errno == TRY_AGAIN) ? "TEMP" : "FAIL", 765 &BlankEnvelope); 766 } 767 else 768 define(macid("{client_resolve}", NULL), "OK", 769 &BlankEnvelope); 770 sm_setproctitle(TRUE, e, "startup with %s", p); 771 772 if ((inchannel = fdopen(t, "r")) == NULL || 773 (t = dup(t)) < 0 || 774 (outchannel = fdopen(t, "w")) == NULL) 775 { 776 syserr("cannot open SMTP server channel, fd=%d", t); 777 finis(FALSE, EX_OK); 778 } 779 780 InChannel = inchannel; 781 OutChannel = outchannel; 782 DisConnected = FALSE; 783 784 # ifdef XLA 785 if (!xla_host_ok(RealHostName)) 786 { 787 message("421 4.4.5 Too many SMTP sessions for this host"); 788 finis(FALSE, EX_OK); 789 } 790 # endif /* XLA */ 791 /* find out name for interface of connection */ 792 if (getsockname(fileno(InChannel), &sa.sa, 793 &len) == 0) 794 { 795 p = hostnamebyanyaddr(&sa); 796 if (tTd(15, 9)) 797 dprintf("getreq: got name %s\n", p); 798 define(macid("{if_name}", NULL), 799 newstr(p), &BlankEnvelope); 800 801 /* do this only if it is not the loopback */ 802 /* interface: how to figure out? XXX */ 803 if (!isloopback(sa)) 804 { 805 define(macid("{if_addr}", NULL), 806 newstr(anynet_ntoa(&sa)), 807 &BlankEnvelope); 808 p = xalloc(5); 809 snprintf(p, 4, "%d", sa.sa.sa_family); 810 define(macid("{if_family}", NULL), p, 811 &BlankEnvelope); 812 if (tTd(15, 7)) 813 dprintf("getreq: got addr %s and family %s\n", 814 macvalue(macid("{if_addr}", NULL), 815 &BlankEnvelope), 816 macvalue(macid("{if_addr}", NULL), 817 &BlankEnvelope)); 818 } 819 else 820 { 821 define(macid("{if_addr}", NULL), NULL, 822 &BlankEnvelope); 823 define(macid("{if_family}", NULL), NULL, 824 &BlankEnvelope); 825 } 826 } 827 else 828 { 829 if (tTd(15, 7)) 830 dprintf("getreq: getsockname failed\n"); 831 define(macid("{if_name}", NULL), NULL, 832 &BlankEnvelope); 833 define(macid("{if_addr}", NULL), NULL, 834 &BlankEnvelope); 835 define(macid("{if_family}", NULL), NULL, 836 &BlankEnvelope); 837 } 838 break; 839 } 840 841 /* parent -- keep track of children */ 842 if (control) 843 { 844 snprintf(status, sizeof status, "control socket server child"); 845 proc_list_add(pid, status, PROC_CONTROL); 846 } 847 else 848 { 849 snprintf(status, sizeof status, 850 "SMTP server child for %s", 851 anynet_ntoa(&RealHostAddr)); 852 proc_list_add(pid, status, PROC_DAEMON); 853 } 854 (void) releasesignal(SIGCHLD); 855 856 /* close the read end of the synchronization pipe */ 857 if (pipefd[0] != -1) 858 { 859 (void) close(pipefd[0]); 860 pipefd[0] = -1; 861 } 862 863 /* close the port so that others will hang (for a while) */ 864 (void) close(t); 865 866 /* release the child by closing the read end of the sync pipe */ 867 if (pipefd[1] != -1) 868 { 869 (void) close(pipefd[1]); 870 pipefd[1] = -1; 871 } 872 } 873 874 if (tTd(15, 2)) 875 dprintf("getreq: returning\n"); 876 return &Daemons[curdaemon].d_flags; 877 } 878 /* 879 ** OPENDAEMONSOCKET -- open SMTP socket 880 ** 881 ** Deals with setting all appropriate options. 882 ** 883 ** Parameters: 884 ** d -- the structure for the daemon to open. 885 ** firsttime -- set if this is the initial open. 886 ** 887 ** Returns: 888 ** Size in bytes of the daemon socket addr. 889 ** 890 ** Side Effects: 891 ** Leaves DaemonSocket set to the open socket. 892 ** Exits if the socket cannot be created. 893 */ 894 895 # define MAXOPENTRIES 10 /* maximum number of tries to open connection */ 896 897 static int 898 opendaemonsocket(d, firsttime) 899 struct daemon *d; 900 bool firsttime; 901 { 902 int on = 1; 903 int fdflags; 904 SOCKADDR_LEN_T socksize = 0; 905 int ntries = 0; 906 int save_errno; 907 908 if (tTd(15, 2)) 909 dprintf("opendaemonsocket(%s)\n", d->d_name); 910 911 do 912 { 913 if (ntries > 0) 914 (void) sleep(5); 915 if (firsttime || d->d_socket < 0) 916 { 917 d->d_socket = socket(d->d_addr.sa.sa_family, 918 SOCK_STREAM, 0); 919 if (d->d_socket < 0) 920 { 921 save_errno = errno; 922 syserr("opendaemonsocket: daemon %s: can't create server SMTP socket", d->d_name); 923 severe: 924 if (LogLevel > 0) 925 sm_syslog(LOG_ALERT, NOQID, 926 "daemon %s: problem creating SMTP socket", d->d_name); 927 d->d_socket = -1; 928 continue; 929 } 930 931 /* turn on network debugging? */ 932 if (tTd(15, 101)) 933 (void) setsockopt(d->d_socket, SOL_SOCKET, 934 SO_DEBUG, (char *)&on, 935 sizeof on); 936 937 (void) setsockopt(d->d_socket, SOL_SOCKET, 938 SO_REUSEADDR, (char *)&on, sizeof on); 939 (void) setsockopt(d->d_socket, SOL_SOCKET, 940 SO_KEEPALIVE, (char *)&on, sizeof on); 941 942 # ifdef SO_RCVBUF 943 if (d->d_tcprcvbufsize > 0) 944 { 945 if (setsockopt(d->d_socket, SOL_SOCKET, 946 SO_RCVBUF, 947 (char *) &d->d_tcprcvbufsize, 948 sizeof(d->d_tcprcvbufsize)) < 0) 949 syserr("opendaemonsocket: daemon %s: setsockopt(SO_RCVBUF)", d->d_name); 950 } 951 # endif /* SO_RCVBUF */ 952 # ifdef SO_SNDBUF 953 if (d->d_tcpsndbufsize > 0) 954 { 955 if (setsockopt(d->d_socket, SOL_SOCKET, 956 SO_SNDBUF, 957 (char *) &d->d_tcpsndbufsize, 958 sizeof(d->d_tcpsndbufsize)) < 0) 959 syserr("opendaemonsocket: daemon %s: setsockopt(SO_SNDBUF)", d->d_name); 960 } 961 # endif /* SO_SNDBUF */ 962 963 if ((fdflags = fcntl(d->d_socket, F_GETFD, 0)) == -1 || 964 fcntl(d->d_socket, F_SETFD, 965 fdflags | FD_CLOEXEC) == -1) 966 { 967 save_errno = errno; 968 syserr("opendaemonsocket: daemon %s: failed to %s close-on-exec flag: %s", 969 d->d_name, 970 fdflags == -1 ? "get" : "set", 971 errstring(save_errno)); 972 (void) close(d->d_socket); 973 goto severe; 974 } 975 976 switch (d->d_addr.sa.sa_family) 977 { 978 # if NETINET 979 case AF_INET: 980 socksize = sizeof d->d_addr.sin; 981 break; 982 # endif /* NETINET */ 983 984 # if NETINET6 985 case AF_INET6: 986 socksize = sizeof d->d_addr.sin6; 987 break; 988 # endif /* NETINET6 */ 989 990 # if NETISO 991 case AF_ISO: 992 socksize = sizeof d->d_addr.siso; 993 break; 994 # endif /* NETISO */ 995 996 default: 997 socksize = sizeof d->d_addr; 998 break; 999 } 1000 1001 if (bind(d->d_socket, &d->d_addr.sa, socksize) < 0) 1002 { 1003 /* probably another daemon already */ 1004 save_errno = errno; 1005 syserr("opendaemonsocket: daemon %s: cannot bind", 1006 d->d_name); 1007 (void) close(d->d_socket); 1008 goto severe; 1009 } 1010 } 1011 if (!firsttime && 1012 listen(d->d_socket, d->d_listenqueue) < 0) 1013 { 1014 save_errno = errno; 1015 syserr("opendaemonsocket: daemon %s: cannot listen", 1016 d->d_name); 1017 (void) close(d->d_socket); 1018 goto severe; 1019 } 1020 return socksize; 1021 } while (ntries++ < MAXOPENTRIES && transienterror(save_errno)); 1022 syserr("!opendaemonsocket: daemon %s: server SMTP socket wedged: exiting", 1023 d->d_name); 1024 /* NOTREACHED */ 1025 return -1; /* avoid compiler warning on IRIX */ 1026 } 1027 /* 1028 ** SETUPDAEMON -- setup socket for daemon 1029 ** 1030 ** Parameters: 1031 ** daemonaddr -- socket for daemon 1032 ** daemon -- number of daemon 1033 ** 1034 ** Returns: 1035 ** port number on which daemon should run 1036 ** 1037 */ 1038 static u_short 1039 setupdaemon(daemonaddr) 1040 SOCKADDR *daemonaddr; 1041 { 1042 u_short port; 1043 1044 /* 1045 ** Set up the address for the mailer. 1046 */ 1047 1048 if (daemonaddr->sa.sa_family == AF_UNSPEC) 1049 { 1050 memset(daemonaddr, '\0', sizeof *daemonaddr); 1051 # if NETINET 1052 daemonaddr->sa.sa_family = AF_INET; 1053 # endif /* NETINET */ 1054 } 1055 1056 switch (daemonaddr->sa.sa_family) 1057 { 1058 # if NETINET 1059 case AF_INET: 1060 if (daemonaddr->sin.sin_addr.s_addr == 0) 1061 daemonaddr->sin.sin_addr.s_addr = INADDR_ANY; 1062 port = daemonaddr->sin.sin_port; 1063 break; 1064 # endif /* NETINET */ 1065 1066 # if NETINET6 1067 case AF_INET6: 1068 if (IN6_IS_ADDR_UNSPECIFIED(&daemonaddr->sin6.sin6_addr)) 1069 daemonaddr->sin6.sin6_addr = in6addr_any; 1070 port = daemonaddr->sin6.sin6_port; 1071 break; 1072 # endif /* NETINET6 */ 1073 1074 default: 1075 /* unknown protocol */ 1076 port = 0; 1077 break; 1078 } 1079 if (port == 0) 1080 { 1081 # ifdef NO_GETSERVBYNAME 1082 port = htons(25); 1083 # else /* NO_GETSERVBYNAME */ 1084 { 1085 register struct servent *sp; 1086 1087 sp = getservbyname("smtp", "tcp"); 1088 if (sp == NULL) 1089 { 1090 syserr("554 5.3.5 service \"smtp\" unknown"); 1091 port = htons(25); 1092 } 1093 else 1094 port = sp->s_port; 1095 } 1096 # endif /* NO_GETSERVBYNAME */ 1097 } 1098 1099 switch (daemonaddr->sa.sa_family) 1100 { 1101 # if NETINET 1102 case AF_INET: 1103 daemonaddr->sin.sin_port = port; 1104 break; 1105 # endif /* NETINET */ 1106 1107 # if NETINET6 1108 case AF_INET6: 1109 daemonaddr->sin6.sin6_port = port; 1110 break; 1111 # endif /* NETINET6 */ 1112 1113 default: 1114 /* unknown protocol */ 1115 break; 1116 } 1117 return(port); 1118 } 1119 /* 1120 ** CLRDAEMON -- reset the daemon connection 1121 ** 1122 ** Parameters: 1123 ** none. 1124 ** 1125 ** Returns: 1126 ** none. 1127 ** 1128 ** Side Effects: 1129 ** releases any resources used by the passive daemon. 1130 */ 1131 1132 void 1133 clrdaemon() 1134 { 1135 int i; 1136 1137 for (i = 0; i < ndaemons; i++) 1138 { 1139 if (Daemons[i].d_socket >= 0) 1140 (void) close(Daemons[i].d_socket); 1141 Daemons[i].d_socket = -1; 1142 } 1143 } 1144 /* 1145 ** SETSOCKADDROPTIONS -- set options for SOCKADDR (daemon or client) 1146 ** 1147 ** Parameters: 1148 ** p -- the options line. 1149 ** d -- the daemon structure to fill in. 1150 ** 1151 ** Returns: 1152 ** none. 1153 */ 1154 1155 static void 1156 setsockaddroptions(p, d) 1157 register char *p; 1158 struct daemon *d; 1159 { 1160 # if NETISO 1161 short portno; 1162 # endif /* NETISO */ 1163 int l; 1164 char *h, *flags; 1165 char *port = NULL; 1166 char *addr = NULL; 1167 1168 # if NETINET 1169 if (d->d_addr.sa.sa_family == AF_UNSPEC) 1170 d->d_addr.sa.sa_family = AF_INET; 1171 # endif /* NETINET */ 1172 1173 while (p != NULL) 1174 { 1175 register char *f; 1176 register char *v; 1177 1178 while (isascii(*p) && isspace(*p)) 1179 p++; 1180 if (*p == '\0') 1181 break; 1182 f = p; 1183 p = strchr(p, ','); 1184 if (p != NULL) 1185 *p++ = '\0'; 1186 v = strchr(f, '='); 1187 if (v == NULL) 1188 continue; 1189 while (isascii(*++v) && isspace(*v)) 1190 continue; 1191 if (isascii(*f) && islower(*f)) 1192 *f = toupper(*f); 1193 1194 switch (*f) 1195 { 1196 case 'F': /* address family */ 1197 if (isascii(*v) && isdigit(*v)) 1198 d->d_addr.sa.sa_family = atoi(v); 1199 # if NETINET 1200 else if (strcasecmp(v, "inet") == 0) 1201 d->d_addr.sa.sa_family = AF_INET; 1202 # endif /* NETINET */ 1203 # if NETINET6 1204 else if (strcasecmp(v, "inet6") == 0) 1205 d->d_addr.sa.sa_family = AF_INET6; 1206 # endif /* NETINET6 */ 1207 # if NETISO 1208 else if (strcasecmp(v, "iso") == 0) 1209 d->d_addr.sa.sa_family = AF_ISO; 1210 # endif /* NETISO */ 1211 # if NETNS 1212 else if (strcasecmp(v, "ns") == 0) 1213 d->d_addr.sa.sa_family = AF_NS; 1214 # endif /* NETNS */ 1215 # if NETX25 1216 else if (strcasecmp(v, "x.25") == 0) 1217 d->d_addr.sa.sa_family = AF_CCITT; 1218 # endif /* NETX25 */ 1219 else 1220 syserr("554 5.3.5 Unknown address family %s in Family=option", 1221 v); 1222 break; 1223 1224 case 'A': /* address */ 1225 addr = v; 1226 break; 1227 1228 case 'P': /* port */ 1229 port = v; 1230 break; 1231 1232 case 'L': /* listen queue size */ 1233 d->d_listenqueue = atoi(v); 1234 break; 1235 1236 case 'M': /* modifiers (flags) */ 1237 l = 3 * strlen(v) + 3; 1238 h = v; 1239 flags = xalloc(l); 1240 d->d_mflags = flags; 1241 for (; *h != '\0'; h++) 1242 { 1243 if (!(isascii(*h) && isspace(*h))) 1244 { 1245 if (flags != d->d_mflags) 1246 *flags++ = ' '; 1247 *flags++ = *h; 1248 if (isupper(*h)) 1249 *flags++ = *h; 1250 } 1251 } 1252 *flags++ = '\0'; 1253 for (; *v != '\0'; v++) 1254 if (!(isascii(*v) && isspace(*v))) 1255 setbitn(bitidx(*v), d->d_flags); 1256 break; 1257 1258 case 'S': /* send buffer size */ 1259 d->d_tcpsndbufsize = atoi(v); 1260 break; 1261 1262 case 'R': /* receive buffer size */ 1263 d->d_tcprcvbufsize = atoi(v); 1264 break; 1265 1266 case 'N': /* name */ 1267 d->d_name = v; 1268 break; 1269 1270 default: 1271 syserr("554 5.3.5 PortOptions parameter \"%s\" unknown", 1272 f); 1273 } 1274 } 1275 1276 /* Check addr and port after finding family */ 1277 if (addr != NULL) 1278 { 1279 switch (d->d_addr.sa.sa_family) 1280 { 1281 # if NETINET 1282 case AF_INET: 1283 if (!isascii(*addr) || !isdigit(*addr) || 1284 ((d->d_addr.sin.sin_addr.s_addr = inet_addr(addr)) == INADDR_NONE)) 1285 { 1286 register struct hostent *hp; 1287 1288 hp = sm_gethostbyname(addr, AF_INET); 1289 if (hp == NULL) 1290 syserr("554 5.3.0 host \"%s\" unknown", 1291 addr); 1292 else 1293 { 1294 while (*(hp->h_addr_list) != NULL && 1295 hp->h_addrtype != AF_INET) 1296 hp->h_addr_list++; 1297 if (*(hp->h_addr_list) == NULL) 1298 syserr("554 5.3.0 host \"%s\" unknown", 1299 addr); 1300 else 1301 memmove(&d->d_addr.sin.sin_addr, 1302 *(hp->h_addr_list), 1303 INADDRSZ); 1304 # if _FFR_FREEHOSTENT && NETINET6 1305 freehostent(hp); 1306 hp = NULL; 1307 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 1308 } 1309 } 1310 break; 1311 # endif /* NETINET */ 1312 1313 # if NETINET6 1314 case AF_INET6: 1315 if (!isascii(*addr) || 1316 (!isxdigit(*addr) && *addr != ':') || 1317 inet_pton(AF_INET6, addr, 1318 &d->d_addr.sin6.sin6_addr) != 1) 1319 { 1320 register struct hostent *hp; 1321 1322 hp = sm_gethostbyname(addr, AF_INET6); 1323 if (hp == NULL) 1324 syserr("554 5.3.0 host \"%s\" unknown", 1325 addr); 1326 else 1327 { 1328 while (*(hp->h_addr_list) != NULL && 1329 hp->h_addrtype != AF_INET6) 1330 hp->h_addr_list++; 1331 if (*(hp->h_addr_list) == NULL) 1332 syserr("554 5.3.0 host \"%s\" unknown", 1333 addr); 1334 else 1335 memmove(&d->d_addr.sin6.sin6_addr, 1336 *(hp->h_addr_list), 1337 IN6ADDRSZ); 1338 # if _FFR_FREEHOSTENT 1339 freehostent(hp); 1340 hp = NULL; 1341 # endif /* _FFR_FREEHOSTENT */ 1342 } 1343 } 1344 break; 1345 # endif /* NETINET6 */ 1346 1347 default: 1348 syserr("554 5.3.5 address= option unsupported for family %d", 1349 d->d_addr.sa.sa_family); 1350 break; 1351 } 1352 } 1353 1354 if (port != NULL) 1355 { 1356 switch (d->d_addr.sa.sa_family) 1357 { 1358 # if NETINET 1359 case AF_INET: 1360 if (isascii(*port) && isdigit(*port)) 1361 d->d_addr.sin.sin_port = htons((u_short)atoi((const char *)port)); 1362 else 1363 { 1364 # ifdef NO_GETSERVBYNAME 1365 syserr("554 5.3.5 invalid port number: %s", 1366 port); 1367 # else /* NO_GETSERVBYNAME */ 1368 register struct servent *sp; 1369 1370 sp = getservbyname(port, "tcp"); 1371 if (sp == NULL) 1372 syserr("554 5.3.5 service \"%s\" unknown", 1373 port); 1374 else 1375 d->d_addr.sin.sin_port = sp->s_port; 1376 # endif /* NO_GETSERVBYNAME */ 1377 } 1378 break; 1379 # endif /* NETINET */ 1380 1381 # if NETINET6 1382 case AF_INET6: 1383 if (isascii(*port) && isdigit(*port)) 1384 d->d_addr.sin6.sin6_port = htons((u_short)atoi(port)); 1385 else 1386 { 1387 # ifdef NO_GETSERVBYNAME 1388 syserr("554 5.3.5 invalid port number: %s", 1389 port); 1390 # else /* NO_GETSERVBYNAME */ 1391 register struct servent *sp; 1392 1393 sp = getservbyname(port, "tcp"); 1394 if (sp == NULL) 1395 syserr("554 5.3.5 service \"%s\" unknown", 1396 port); 1397 else 1398 d->d_addr.sin6.sin6_port = sp->s_port; 1399 # endif /* NO_GETSERVBYNAME */ 1400 } 1401 break; 1402 # endif /* NETINET6 */ 1403 1404 # if NETISO 1405 case AF_ISO: 1406 /* assume two byte transport selector */ 1407 if (isascii(*port) && isdigit(*port)) 1408 portno = htons((u_short)atoi(port)); 1409 else 1410 { 1411 # ifdef NO_GETSERVBYNAME 1412 syserr("554 5.3.5 invalid port number: %s", 1413 port); 1414 # else /* NO_GETSERVBYNAME */ 1415 register struct servent *sp; 1416 1417 sp = getservbyname(port, "tcp"); 1418 if (sp == NULL) 1419 syserr("554 5.3.5 service \"%s\" unknown", 1420 port); 1421 else 1422 portno = sp->s_port; 1423 # endif /* NO_GETSERVBYNAME */ 1424 } 1425 memmove(TSEL(&d->d_addr.siso), 1426 (char *) &portno, 2); 1427 break; 1428 # endif /* NETISO */ 1429 1430 default: 1431 syserr("554 5.3.5 Port= option unsupported for family %d", 1432 d->d_addr.sa.sa_family); 1433 break; 1434 } 1435 } 1436 } 1437 /* 1438 ** SETDAEMONOPTIONS -- set options for running the MTA daemon 1439 ** 1440 ** Parameters: 1441 ** p -- the options line. 1442 ** 1443 ** Returns: 1444 ** TRUE if successful, FALSE otherwise. 1445 */ 1446 1447 bool 1448 setdaemonoptions(p) 1449 register char *p; 1450 { 1451 if (ndaemons >= MAXDAEMONS) 1452 return FALSE; 1453 Daemons[ndaemons].d_socket = -1; 1454 Daemons[ndaemons].d_listenqueue = 10; 1455 clrbitmap(Daemons[ndaemons].d_flags); 1456 setsockaddroptions(p, &Daemons[ndaemons]); 1457 1458 if (Daemons[ndaemons].d_name != NULL) 1459 Daemons[ndaemons].d_name = newstr(Daemons[ndaemons].d_name); 1460 else 1461 { 1462 char num[30]; 1463 1464 snprintf(num, sizeof num, "Daemon%d", ndaemons); 1465 Daemons[ndaemons].d_name = newstr(num); 1466 } 1467 1468 if (tTd(37, 1)) 1469 { 1470 dprintf("Daemon %s flags: ", Daemons[ndaemons].d_name); 1471 if (bitnset(D_ETRNONLY, Daemons[ndaemons].d_flags)) 1472 dprintf("ETRNONLY "); 1473 if (bitnset(D_NOETRN, Daemons[ndaemons].d_flags)) 1474 dprintf("NOETRN "); 1475 dprintf("\n"); 1476 } 1477 ++ndaemons; 1478 return TRUE; 1479 } 1480 /* 1481 ** INITDAEMON -- initialize daemon if not yet done. 1482 ** 1483 ** Parameters: 1484 ** none 1485 ** 1486 ** Returns: 1487 ** none 1488 ** 1489 ** Side Effects: 1490 ** initializes structure for one daemon. 1491 */ 1492 void 1493 initdaemon() 1494 { 1495 if (ndaemons == 0) 1496 { 1497 Daemons[ndaemons].d_socket = -1; 1498 Daemons[ndaemons].d_listenqueue = 10; 1499 Daemons[ndaemons].d_name = "Daemon0"; 1500 ndaemons = 1; 1501 } 1502 } 1503 /* 1504 ** SETCLIENTOPTIONS -- set options for running the client 1505 ** 1506 ** Parameters: 1507 ** p -- the options line. 1508 ** 1509 ** Returns: 1510 ** none. 1511 */ 1512 1513 static SOCKADDR ClientAddr; /* address for client */ 1514 1515 void 1516 setclientoptions(p) 1517 register char *p; 1518 { 1519 struct daemon d; 1520 extern ENVELOPE BlankEnvelope; 1521 1522 memset(&d, '\0', sizeof d); 1523 setsockaddroptions(p, &d); 1524 1525 /* grab what we need */ 1526 memcpy(&ClientAddr, &d.d_addr, sizeof ClientAddr); 1527 TcpSndBufferSize = d.d_tcpsndbufsize; 1528 TcpRcvBufferSize = d.d_tcprcvbufsize; 1529 if (d.d_mflags != NULL) 1530 define(macid("{client_flags}", NULL), d.d_mflags, 1531 &BlankEnvelope); 1532 else 1533 define(macid("{client_flags}", NULL), "", &BlankEnvelope); 1534 } 1535 /* 1536 ** ADDR_FAMILY -- determine address family from address 1537 ** 1538 ** Parameters: 1539 ** addr -- the string representation of the address 1540 ** 1541 ** Returns: 1542 ** AF_INET, AF_INET6 or AF_UNSPEC 1543 ** 1544 ** Side Effects: 1545 ** none. 1546 */ 1547 1548 static int 1549 addr_family(addr) 1550 char *addr; 1551 { 1552 # if NETINET6 1553 SOCKADDR clt_addr; 1554 # endif /* NETINET6 */ 1555 1556 # if NETINET 1557 if (inet_addr(addr) != INADDR_NONE) 1558 { 1559 if (tTd(16, 9)) 1560 printf("addr_family(%s): INET\n", addr); 1561 return AF_INET; 1562 } 1563 # endif /* NETINET */ 1564 # if NETINET6 1565 if (inet_pton(AF_INET6, addr, &clt_addr.sin6.sin6_addr) == 1) 1566 { 1567 if (tTd(16, 9)) 1568 printf("addr_family(%s): INET6\n", addr); 1569 return AF_INET6; 1570 } 1571 # endif /* NETINET6 */ 1572 if (tTd(16, 9)) 1573 printf("addr_family(%s): UNSPEC\n", addr); 1574 return AF_UNSPEC; 1575 } 1576 /* 1577 ** MAKECONNECTION -- make a connection to an SMTP socket on a machine. 1578 ** 1579 ** Parameters: 1580 ** host -- the name of the host. 1581 ** port -- the port number to connect to. 1582 ** mci -- a pointer to the mail connection information 1583 ** structure to be filled in. 1584 ** e -- the current envelope. 1585 ** 1586 ** Returns: 1587 ** An exit code telling whether the connection could be 1588 ** made and if not why not. 1589 ** 1590 ** Side Effects: 1591 ** none. 1592 */ 1593 1594 static jmp_buf CtxConnectTimeout; 1595 1596 SOCKADDR CurHostAddr; /* address of current host */ 1597 1598 int 1599 makeconnection(host, port, mci, e) 1600 char *host; 1601 volatile u_int port; 1602 register MCI *mci; 1603 ENVELOPE *e; 1604 { 1605 register volatile int addrno = 0; 1606 register volatile int s; 1607 register struct hostent *volatile hp = (struct hostent *)NULL; 1608 SOCKADDR addr; 1609 SOCKADDR clt_addr; 1610 int save_errno = 0; 1611 volatile SOCKADDR_LEN_T addrlen; 1612 volatile bool firstconnect; 1613 EVENT *volatile ev = NULL; 1614 # if NETINET6 1615 volatile bool v6found = FALSE; 1616 # endif /* NETINET6 */ 1617 volatile int family = InetMode; 1618 SOCKADDR_LEN_T len; 1619 volatile SOCKADDR_LEN_T socksize = 0; 1620 volatile bool clt_bind; 1621 BITMAP256 d_flags; 1622 char *p; 1623 extern ENVELOPE BlankEnvelope; 1624 1625 /* retranslate ${daemon_flags} into bitmap */ 1626 clrbitmap(d_flags); 1627 if ((p = macvalue(macid("{daemon_flags}", NULL), e)) != NULL) 1628 { 1629 for (; *p != '\0'; p++) 1630 { 1631 if (!(isascii(*p) && isspace(*p))) 1632 setbitn(bitidx(*p), d_flags); 1633 } 1634 } 1635 1636 /* "add" ${client_flags} to bitmap */ 1637 if ((p = macvalue(macid("{client_flags}", NULL), e)) != NULL) 1638 { 1639 for (; *p != '\0'; p++) 1640 { 1641 /* look for just this one flag */ 1642 if (*p == D_IFNHELO) 1643 { 1644 setbitn(bitidx(*p), d_flags); 1645 break; 1646 } 1647 } 1648 } 1649 1650 # if NETINET6 1651 v4retry: 1652 # endif /* NETINET6 */ 1653 clt_bind = FALSE; 1654 1655 /* Set up the address for outgoing connection. */ 1656 if (bitnset(D_BINDIF, d_flags) && 1657 (p = macvalue(macid("{if_addr}", NULL), e)) != NULL && 1658 *p != '\0') 1659 { 1660 # if NETINET6 1661 char p6[INET6_ADDRSTRLEN]; 1662 # endif /* NETINET6 */ 1663 1664 memset(&clt_addr, '\0', sizeof clt_addr); 1665 1666 /* infer the address family from the address itself */ 1667 clt_addr.sa.sa_family = addr_family(p); 1668 switch (clt_addr.sa.sa_family) 1669 { 1670 # if NETINET 1671 case AF_INET: 1672 clt_addr.sin.sin_addr.s_addr = inet_addr(p); 1673 if (clt_addr.sin.sin_addr.s_addr != INADDR_NONE && 1674 clt_addr.sin.sin_addr.s_addr != INADDR_LOOPBACK) 1675 { 1676 clt_bind = TRUE; 1677 socksize = sizeof (struct sockaddr_in); 1678 } 1679 break; 1680 # endif /* NETINET */ 1681 1682 # if NETINET6 1683 case AF_INET6: 1684 if (inet_addr(p) != INADDR_NONE) 1685 snprintf(p6, sizeof p6, "::ffff:%s", p); 1686 else 1687 strlcpy(p6, p, sizeof p6); 1688 if (inet_pton(AF_INET6, p6, 1689 &clt_addr.sin6.sin6_addr) == 1 && 1690 !IN6_IS_ADDR_LOOPBACK(&clt_addr.sin6.sin6_addr)) 1691 { 1692 clt_bind = TRUE; 1693 socksize = sizeof (struct sockaddr_in6); 1694 } 1695 break; 1696 # endif /* NETINET6 */ 1697 1698 # if 0 1699 default: 1700 syserr("554 5.3.5 Address= option unsupported for family %d", 1701 clt_addr.sa.sa_family); 1702 break; 1703 # endif /* 0 */ 1704 } 1705 if (clt_bind) 1706 family = clt_addr.sa.sa_family; 1707 } 1708 else 1709 { 1710 STRUCTCOPY(ClientAddr, clt_addr); 1711 if (clt_addr.sa.sa_family == AF_UNSPEC) 1712 clt_addr.sa.sa_family = InetMode; 1713 switch (clt_addr.sa.sa_family) 1714 { 1715 # if NETINET 1716 case AF_INET: 1717 if (clt_addr.sin.sin_addr.s_addr == 0) 1718 clt_addr.sin.sin_addr.s_addr = INADDR_ANY; 1719 else 1720 clt_bind = TRUE; 1721 if (clt_addr.sin.sin_port != 0) 1722 clt_bind = TRUE; 1723 socksize = sizeof (struct sockaddr_in); 1724 break; 1725 # endif /* NETINET */ 1726 # if NETINET6 1727 case AF_INET6: 1728 if (IN6_IS_ADDR_UNSPECIFIED(&clt_addr.sin6.sin6_addr)) 1729 clt_addr.sin6.sin6_addr = in6addr_any; 1730 else 1731 clt_bind = TRUE; 1732 socksize = sizeof (struct sockaddr_in6); 1733 if (clt_addr.sin6.sin6_port != 0) 1734 clt_bind = TRUE; 1735 break; 1736 # endif /* NETINET6 */ 1737 # if NETISO 1738 case AF_ISO: 1739 socksize = sizeof clt_addr.siso; 1740 clt_bind = TRUE; 1741 break; 1742 # endif /* NETISO */ 1743 default: 1744 break; 1745 } 1746 } 1747 1748 /* 1749 ** Set up the address for the mailer. 1750 ** Accept "[a.b.c.d]" syntax for host name. 1751 */ 1752 1753 # if NAMED_BIND 1754 SM_SET_H_ERRNO(0); 1755 # endif /* NAMED_BIND */ 1756 errno = 0; 1757 memset(&CurHostAddr, '\0', sizeof CurHostAddr); 1758 memset(&addr, '\0', sizeof addr); 1759 SmtpPhase = mci->mci_phase = "initial connection"; 1760 CurHostName = host; 1761 1762 if (host[0] == '[') 1763 { 1764 p = strchr(host, ']'); 1765 if (p != NULL) 1766 { 1767 # if NETINET 1768 unsigned long hid = INADDR_NONE; 1769 # endif /* NETINET */ 1770 # if NETINET6 1771 struct sockaddr_in6 hid6; 1772 # endif /* NETINET6 */ 1773 1774 *p = '\0'; 1775 # if NETINET6 1776 memset(&hid6, '\0', sizeof hid6); 1777 # endif /* NETINET6 */ 1778 # if NETINET 1779 if (family == AF_INET && 1780 (hid = inet_addr(&host[1])) != INADDR_NONE) 1781 { 1782 addr.sin.sin_family = AF_INET; 1783 addr.sin.sin_addr.s_addr = hid; 1784 } 1785 else 1786 # endif /* NETINET */ 1787 # if NETINET6 1788 if (family == AF_INET6 && 1789 inet_pton(AF_INET6, &host[1], 1790 &hid6.sin6_addr) == 1) 1791 { 1792 addr.sin6.sin6_family = AF_INET6; 1793 addr.sin6.sin6_addr = hid6.sin6_addr; 1794 } 1795 else 1796 # endif /* NETINET6 */ 1797 { 1798 /* try it as a host name (avoid MX lookup) */ 1799 hp = sm_gethostbyname(&host[1], family); 1800 if (hp == NULL && p[-1] == '.') 1801 { 1802 # if NAMED_BIND 1803 int oldopts = _res.options; 1804 1805 _res.options &= ~(RES_DEFNAMES|RES_DNSRCH); 1806 # endif /* NAMED_BIND */ 1807 p[-1] = '\0'; 1808 hp = sm_gethostbyname(&host[1], 1809 family); 1810 p[-1] = '.'; 1811 # if NAMED_BIND 1812 _res.options = oldopts; 1813 # endif /* NAMED_BIND */ 1814 } 1815 *p = ']'; 1816 goto gothostent; 1817 } 1818 *p = ']'; 1819 } 1820 if (p == NULL) 1821 { 1822 extern char MsgBuf[]; 1823 1824 usrerrenh("5.1.2", 1825 "553 Invalid numeric domain spec \"%s\"", 1826 host); 1827 mci_setstat(mci, EX_NOHOST, "5.1.2", MsgBuf); 1828 errno = EINVAL; 1829 return EX_NOHOST; 1830 } 1831 } 1832 else 1833 { 1834 /* contortion to get around SGI cc complaints */ 1835 { 1836 p = &host[strlen(host) - 1]; 1837 hp = sm_gethostbyname(host, family); 1838 if (hp == NULL && *p == '.') 1839 { 1840 # if NAMED_BIND 1841 int oldopts = _res.options; 1842 1843 _res.options &= ~(RES_DEFNAMES|RES_DNSRCH); 1844 # endif /* NAMED_BIND */ 1845 *p = '\0'; 1846 hp = sm_gethostbyname(host, family); 1847 *p = '.'; 1848 # if NAMED_BIND 1849 _res.options = oldopts; 1850 # endif /* NAMED_BIND */ 1851 } 1852 } 1853 gothostent: 1854 if (hp == NULL) 1855 { 1856 # if NAMED_BIND 1857 /* check for name server timeouts */ 1858 if (errno == ETIMEDOUT || h_errno == TRY_AGAIN || 1859 (errno == ECONNREFUSED && UseNameServer)) 1860 { 1861 save_errno = errno; 1862 mci_setstat(mci, EX_TEMPFAIL, "4.4.3", NULL); 1863 errno = save_errno; 1864 return EX_TEMPFAIL; 1865 } 1866 # endif /* NAMED_BIND */ 1867 # if NETINET6 1868 /* 1869 ** Try v6 first, then fall back to v4. 1870 ** If we found a v6 address, but no v4 1871 ** addresses, then TEMPFAIL. 1872 */ 1873 1874 if (family == AF_INET6) 1875 { 1876 family = AF_INET; 1877 goto v4retry; 1878 } 1879 if (v6found) 1880 goto v6tempfail; 1881 # endif /* NETINET6 */ 1882 save_errno = errno; 1883 mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); 1884 errno = save_errno; 1885 return EX_NOHOST; 1886 } 1887 addr.sa.sa_family = hp->h_addrtype; 1888 switch (hp->h_addrtype) 1889 { 1890 # if NETINET 1891 case AF_INET: 1892 memmove(&addr.sin.sin_addr, 1893 hp->h_addr, 1894 INADDRSZ); 1895 break; 1896 # endif /* NETINET */ 1897 1898 # if NETINET6 1899 case AF_INET6: 1900 memmove(&addr.sin6.sin6_addr, 1901 hp->h_addr, 1902 IN6ADDRSZ); 1903 break; 1904 # endif /* NETINET6 */ 1905 1906 default: 1907 if (hp->h_length > sizeof addr.sa.sa_data) 1908 { 1909 syserr("makeconnection: long sa_data: family %d len %d", 1910 hp->h_addrtype, hp->h_length); 1911 mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); 1912 errno = EINVAL; 1913 return EX_NOHOST; 1914 } 1915 memmove(addr.sa.sa_data, 1916 hp->h_addr, 1917 hp->h_length); 1918 break; 1919 } 1920 addrno = 1; 1921 } 1922 1923 /* 1924 ** Determine the port number. 1925 */ 1926 1927 if (port == 0) 1928 { 1929 # ifdef NO_GETSERVBYNAME 1930 port = htons(25); 1931 # else /* NO_GETSERVBYNAME */ 1932 register struct servent *sp = getservbyname("smtp", "tcp"); 1933 1934 if (sp == NULL) 1935 { 1936 if (LogLevel > 2) 1937 sm_syslog(LOG_ERR, NOQID, 1938 "makeconnection: service \"smtp\" unknown"); 1939 port = htons(25); 1940 } 1941 else 1942 port = sp->s_port; 1943 # endif /* NO_GETSERVBYNAME */ 1944 } 1945 1946 switch (addr.sa.sa_family) 1947 { 1948 # if NETINET 1949 case AF_INET: 1950 addr.sin.sin_port = port; 1951 addrlen = sizeof (struct sockaddr_in); 1952 break; 1953 # endif /* NETINET */ 1954 1955 # if NETINET6 1956 case AF_INET6: 1957 addr.sin6.sin6_port = port; 1958 addrlen = sizeof (struct sockaddr_in6); 1959 break; 1960 # endif /* NETINET6 */ 1961 1962 # if NETISO 1963 case AF_ISO: 1964 /* assume two byte transport selector */ 1965 memmove(TSEL((struct sockaddr_iso *) &addr), (char *) &port, 2); 1966 addrlen = sizeof (struct sockaddr_iso); 1967 break; 1968 # endif /* NETISO */ 1969 1970 default: 1971 syserr("Can't connect to address family %d", addr.sa.sa_family); 1972 mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); 1973 errno = EINVAL; 1974 # if _FFR_FREEHOSTENT && NETINET6 1975 if (hp != NULL) 1976 freehostent(hp); 1977 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 1978 return EX_NOHOST; 1979 } 1980 1981 /* 1982 ** Try to actually open the connection. 1983 */ 1984 1985 # ifdef XLA 1986 /* if too many connections, don't bother trying */ 1987 if (!xla_noqueue_ok(host)) 1988 { 1989 # if _FFR_FREEHOSTENT && NETINET6 1990 if (hp != NULL) 1991 freehostent(hp); 1992 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 1993 return EX_TEMPFAIL; 1994 } 1995 # endif /* XLA */ 1996 1997 firstconnect = TRUE; 1998 for (;;) 1999 { 2000 if (tTd(16, 1)) 2001 dprintf("makeconnection (%s [%s])\n", 2002 host, anynet_ntoa(&addr)); 2003 2004 /* save for logging */ 2005 CurHostAddr = addr; 2006 2007 if (bitnset(M_SECURE_PORT, mci->mci_mailer->m_flags)) 2008 { 2009 int rport = IPPORT_RESERVED - 1; 2010 2011 s = rresvport(&rport); 2012 } 2013 else 2014 { 2015 s = socket(addr.sa.sa_family, SOCK_STREAM, 0); 2016 } 2017 if (s < 0) 2018 { 2019 save_errno = errno; 2020 syserr("makeconnection: cannot create socket"); 2021 # ifdef XLA 2022 xla_host_end(host); 2023 # endif /* XLA */ 2024 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2025 # if _FFR_FREEHOSTENT && NETINET6 2026 if (hp != NULL) 2027 freehostent(hp); 2028 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 2029 errno = save_errno; 2030 return EX_TEMPFAIL; 2031 } 2032 2033 # ifdef SO_SNDBUF 2034 if (TcpSndBufferSize > 0) 2035 { 2036 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, 2037 (char *) &TcpSndBufferSize, 2038 sizeof(TcpSndBufferSize)) < 0) 2039 syserr("makeconnection: setsockopt(SO_SNDBUF)"); 2040 } 2041 # endif /* SO_SNDBUF */ 2042 # ifdef SO_RCVBUF 2043 if (TcpRcvBufferSize > 0) 2044 { 2045 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 2046 (char *) &TcpRcvBufferSize, 2047 sizeof(TcpRcvBufferSize)) < 0) 2048 syserr("makeconnection: setsockopt(SO_RCVBUF)"); 2049 } 2050 # endif /* SO_RCVBUF */ 2051 2052 2053 if (tTd(16, 1)) 2054 dprintf("makeconnection: fd=%d\n", s); 2055 2056 /* turn on network debugging? */ 2057 if (tTd(16, 101)) 2058 { 2059 int on = 1; 2060 2061 (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, 2062 (char *)&on, sizeof on); 2063 } 2064 if (e->e_xfp != NULL) 2065 (void) fflush(e->e_xfp); /* for debugging */ 2066 errno = 0; /* for debugging */ 2067 2068 if (clt_bind) 2069 { 2070 int on = 1; 2071 2072 switch (clt_addr.sa.sa_family) 2073 { 2074 # if NETINET 2075 case AF_INET: 2076 if (clt_addr.sin.sin_port != 0) 2077 (void) setsockopt(s, SOL_SOCKET, 2078 SO_REUSEADDR, 2079 (char *) &on, 2080 sizeof on); 2081 break; 2082 # endif /* NETINET */ 2083 2084 # if NETINET6 2085 case AF_INET6: 2086 if (clt_addr.sin6.sin6_port != 0) 2087 (void) setsockopt(s, SOL_SOCKET, 2088 SO_REUSEADDR, 2089 (char *) &on, 2090 sizeof on); 2091 break; 2092 # endif /* NETINET6 */ 2093 } 2094 2095 if (bind(s, &clt_addr.sa, socksize) < 0) 2096 { 2097 save_errno = errno; 2098 (void) close(s); 2099 errno = save_errno; 2100 syserr("makeconnection: cannot bind socket [%s]", 2101 anynet_ntoa(&clt_addr)); 2102 # if _FFR_FREEHOSTENT && NETINET6 2103 if (hp != NULL) 2104 freehostent(hp); 2105 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 2106 errno = save_errno; 2107 return EX_TEMPFAIL; 2108 } 2109 } 2110 2111 /* 2112 ** Linux seems to hang in connect for 90 minutes (!!!). 2113 ** Time out the connect to avoid this problem. 2114 */ 2115 2116 if (setjmp(CtxConnectTimeout) == 0) 2117 { 2118 int i; 2119 2120 if (e->e_ntries <= 0 && TimeOuts.to_iconnect != 0) 2121 ev = setevent(TimeOuts.to_iconnect, connecttimeout, 0); 2122 else if (TimeOuts.to_connect != 0) 2123 ev = setevent(TimeOuts.to_connect, connecttimeout, 0); 2124 else 2125 ev = NULL; 2126 2127 switch (ConnectOnlyTo.sa.sa_family) 2128 { 2129 # if NETINET 2130 case AF_INET: 2131 addr.sin.sin_addr.s_addr = ConnectOnlyTo.sin.sin_addr.s_addr; 2132 break; 2133 # endif /* NETINET */ 2134 2135 # if NETINET6 2136 case AF_INET6: 2137 memmove(&addr.sin6.sin6_addr, 2138 &ConnectOnlyTo.sin6.sin6_addr, 2139 IN6ADDRSZ); 2140 break; 2141 # endif /* NETINET6 */ 2142 } 2143 i = connect(s, (struct sockaddr *) &addr, addrlen); 2144 save_errno = errno; 2145 if (ev != NULL) 2146 clrevent(ev); 2147 if (i >= 0) 2148 break; 2149 } 2150 else 2151 save_errno = errno; 2152 2153 /* if running demand-dialed connection, try again */ 2154 if (DialDelay > 0 && firstconnect) 2155 { 2156 if (tTd(16, 1)) 2157 dprintf("Connect failed (%s); trying again...\n", 2158 errstring(save_errno)); 2159 firstconnect = FALSE; 2160 (void) sleep(DialDelay); 2161 continue; 2162 } 2163 2164 /* couldn't connect.... figure out why */ 2165 (void) close(s); 2166 2167 if (LogLevel >= 14) 2168 sm_syslog(LOG_INFO, e->e_id, 2169 "makeconnection (%s [%s]) failed: %s", 2170 host, anynet_ntoa(&addr), 2171 errstring(save_errno)); 2172 2173 if (hp != NULL && hp->h_addr_list[addrno] != NULL) 2174 { 2175 if (tTd(16, 1)) 2176 dprintf("Connect failed (%s); trying new address....\n", 2177 errstring(save_errno)); 2178 switch (addr.sa.sa_family) 2179 { 2180 # if NETINET 2181 case AF_INET: 2182 memmove(&addr.sin.sin_addr, 2183 hp->h_addr_list[addrno++], 2184 INADDRSZ); 2185 break; 2186 # endif /* NETINET */ 2187 2188 # if NETINET6 2189 case AF_INET6: 2190 memmove(&addr.sin6.sin6_addr, 2191 hp->h_addr_list[addrno++], 2192 IN6ADDRSZ); 2193 break; 2194 # endif /* NETINET6 */ 2195 2196 default: 2197 memmove(addr.sa.sa_data, 2198 hp->h_addr_list[addrno++], 2199 hp->h_length); 2200 break; 2201 } 2202 continue; 2203 } 2204 errno = save_errno; 2205 2206 # if NETINET6 2207 if (family == AF_INET6) 2208 { 2209 if (tTd(16, 1)) 2210 dprintf("Connect failed (%s); retrying with AF_INET....\n", 2211 errstring(save_errno)); 2212 v6found = TRUE; 2213 family = AF_INET; 2214 # if _FFR_FREEHOSTENT 2215 if (hp != NULL) 2216 { 2217 freehostent(hp); 2218 hp = NULL; 2219 } 2220 # endif /* _FFR_FREEHOSTENT */ 2221 goto v4retry; 2222 } 2223 v6tempfail: 2224 # endif /* NETINET6 */ 2225 /* couldn't open connection */ 2226 # if NETINET6 2227 /* Don't clobber an already saved errno from v4retry */ 2228 if (errno > 0) 2229 # endif /* NETINET6 */ 2230 save_errno = errno; 2231 if (tTd(16, 1)) 2232 dprintf("Connect failed (%s)\n", errstring(save_errno)); 2233 # ifdef XLA 2234 xla_host_end(host); 2235 # endif /* XLA */ 2236 mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); 2237 # if _FFR_FREEHOSTENT && NETINET6 2238 if (hp != NULL) 2239 freehostent(hp); 2240 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 2241 errno = save_errno; 2242 return EX_TEMPFAIL; 2243 } 2244 2245 # if _FFR_FREEHOSTENT && NETINET6 2246 if (hp != NULL) 2247 { 2248 freehostent(hp); 2249 hp = NULL; 2250 } 2251 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 2252 2253 /* connection ok, put it into canonical form */ 2254 mci->mci_out = NULL; 2255 if ((mci->mci_out = fdopen(s, "w")) == NULL || 2256 (s = dup(s)) < 0 || 2257 (mci->mci_in = fdopen(s, "r")) == NULL) 2258 { 2259 save_errno = errno; 2260 syserr("cannot open SMTP client channel, fd=%d", s); 2261 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2262 if (mci->mci_out != NULL) 2263 (void) fclose(mci->mci_out); 2264 (void) close(s); 2265 errno = save_errno; 2266 return EX_TEMPFAIL; 2267 } 2268 2269 /* find out name for Interface through which we connect */ 2270 len = sizeof addr; 2271 if (getsockname(s, &addr.sa, &len) == 0) 2272 { 2273 char *name; 2274 char *p; 2275 2276 define(macid("{if_addr}", NULL), newstr(anynet_ntoa(&addr)), 2277 &BlankEnvelope); 2278 p = xalloc(5); 2279 snprintf(p, 4, "%d", addr.sa.sa_family); 2280 define(macid("{if_family}", NULL), p, &BlankEnvelope); 2281 2282 name = hostnamebyanyaddr(&addr); 2283 define(macid("{if_name}", NULL), newstr(name), &BlankEnvelope); 2284 if (LogLevel > 11) 2285 { 2286 /* log connection information */ 2287 sm_syslog(LOG_INFO, e->e_id, 2288 "SMTP outgoing connect on %.40s", name); 2289 } 2290 if (bitnset(D_IFNHELO, d_flags)) 2291 { 2292 if (name[0] != '[' && strchr(name, '.') != NULL) 2293 mci->mci_heloname = newstr(name); 2294 } 2295 } 2296 else 2297 { 2298 define(macid("{if_name}", NULL), NULL, &BlankEnvelope); 2299 define(macid("{if_addr}", NULL), NULL, &BlankEnvelope); 2300 define(macid("{if_family}", NULL), NULL, &BlankEnvelope); 2301 } 2302 mci_setstat(mci, EX_OK, NULL, NULL); 2303 return EX_OK; 2304 } 2305 2306 static void 2307 connecttimeout() 2308 { 2309 errno = ETIMEDOUT; 2310 longjmp(CtxConnectTimeout, 1); 2311 } 2312 /* 2313 ** MAKECONNECTION_DS -- make a connection to a domain socket. 2314 ** 2315 ** Parameters: 2316 ** mux_path -- the path of the socket to connect to. 2317 ** mci -- a pointer to the mail connection information 2318 ** structure to be filled in. 2319 ** 2320 ** Returns: 2321 ** An exit code telling whether the connection could be 2322 ** made and if not why not. 2323 ** 2324 ** Side Effects: 2325 ** none. 2326 */ 2327 2328 # if NETUNIX 2329 int makeconnection_ds(mux_path, mci) 2330 char *mux_path; 2331 register MCI *mci; 2332 { 2333 int sock; 2334 int rval, save_errno; 2335 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_ROOTOK|SFF_EXECOK; 2336 struct sockaddr_un unix_addr; 2337 2338 /* if not safe, don't connect */ 2339 rval = safefile(mux_path, RunAsUid, RunAsGid, RunAsUserName, 2340 sff, S_IRUSR|S_IWUSR, NULL); 2341 2342 if (rval != 0) 2343 { 2344 syserr("makeconnection_ds: unsafe domain socket"); 2345 mci_setstat(mci, EX_TEMPFAIL, "4.3.5", NULL); 2346 errno = rval; 2347 return EX_TEMPFAIL; 2348 } 2349 2350 /* prepare address structure */ 2351 memset(&unix_addr, '\0', sizeof unix_addr); 2352 unix_addr.sun_family = AF_UNIX; 2353 2354 if (strlen(mux_path) >= sizeof unix_addr.sun_path) 2355 { 2356 syserr("makeconnection_ds: domain socket name too long"); 2357 /* XXX why TEMPFAIL ? */ 2358 mci_setstat(mci, EX_TEMPFAIL, "5.3.5", NULL); 2359 errno = ENAMETOOLONG; 2360 return EX_UNAVAILABLE; 2361 } 2362 (void) strlcpy(unix_addr.sun_path, mux_path, sizeof unix_addr.sun_path); 2363 2364 /* initialize domain socket */ 2365 sock = socket(AF_UNIX, SOCK_STREAM, 0); 2366 if (sock == -1) 2367 { 2368 save_errno = errno; 2369 syserr("makeconnection_ds: could not create domain socket"); 2370 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2371 errno = save_errno; 2372 return EX_TEMPFAIL; 2373 } 2374 2375 /* connect to server */ 2376 if (connect(sock, (struct sockaddr *) &unix_addr, 2377 sizeof(unix_addr)) == -1) 2378 { 2379 save_errno = errno; 2380 syserr("Could not connect to socket %s", mux_path); 2381 mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); 2382 (void) close(sock); 2383 errno = save_errno; 2384 return EX_TEMPFAIL; 2385 } 2386 2387 /* connection ok, put it into canonical form */ 2388 mci->mci_out = NULL; 2389 if ((mci->mci_out = fdopen(sock, "w")) == NULL || 2390 (sock = dup(sock)) < 0 || 2391 (mci->mci_in = fdopen(sock, "r")) == NULL) 2392 { 2393 save_errno = errno; 2394 syserr("cannot open SMTP client channel, fd=%d", sock); 2395 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2396 if (mci->mci_out != NULL) 2397 (void) fclose(mci->mci_out); 2398 (void) close(sock); 2399 errno = save_errno; 2400 return EX_TEMPFAIL; 2401 } 2402 2403 mci_setstat(mci, EX_OK, NULL, NULL); 2404 errno = 0; 2405 return EX_OK; 2406 } 2407 # endif /* NETUNIX */ 2408 /* 2409 ** MYHOSTNAME -- return the name of this host. 2410 ** 2411 ** Parameters: 2412 ** hostbuf -- a place to return the name of this host. 2413 ** size -- the size of hostbuf. 2414 ** 2415 ** Returns: 2416 ** A list of aliases for this host. 2417 ** 2418 ** Side Effects: 2419 ** Adds numeric codes to $=w. 2420 */ 2421 2422 struct hostent * 2423 myhostname(hostbuf, size) 2424 char hostbuf[]; 2425 int size; 2426 { 2427 register struct hostent *hp; 2428 2429 if (gethostname(hostbuf, size) < 0 || hostbuf[0] == '\0') 2430 (void) strlcpy(hostbuf, "localhost", size); 2431 hp = sm_gethostbyname(hostbuf, InetMode); 2432 if (hp == NULL) 2433 return NULL; 2434 if (strchr(hp->h_name, '.') != NULL || strchr(hostbuf, '.') == NULL) 2435 (void) cleanstrcpy(hostbuf, hp->h_name, size); 2436 2437 # if NETINFO 2438 if (strchr(hostbuf, '.') == NULL) 2439 { 2440 char *domainname; 2441 2442 domainname = ni_propval("/locations", NULL, "resolver", 2443 "domain", '\0'); 2444 if (domainname != NULL && 2445 strlen(domainname) + strlen(hostbuf) + 1 < size) 2446 { 2447 (void) strlcat(hostbuf, ".", size); 2448 (void) strlcat(hostbuf, domainname, size); 2449 } 2450 } 2451 # endif /* NETINFO */ 2452 2453 /* 2454 ** If there is still no dot in the name, try looking for a 2455 ** dotted alias. 2456 */ 2457 2458 if (strchr(hostbuf, '.') == NULL) 2459 { 2460 char **ha; 2461 2462 for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++) 2463 { 2464 if (strchr(*ha, '.') != NULL) 2465 { 2466 (void) cleanstrcpy(hostbuf, *ha, size - 1); 2467 hostbuf[size - 1] = '\0'; 2468 break; 2469 } 2470 } 2471 } 2472 2473 /* 2474 ** If _still_ no dot, wait for a while and try again -- it is 2475 ** possible that some service is starting up. This can result 2476 ** in excessive delays if the system is badly configured, but 2477 ** there really isn't a way around that, particularly given that 2478 ** the config file hasn't been read at this point. 2479 ** All in all, a bit of a mess. 2480 */ 2481 2482 if (strchr(hostbuf, '.') == NULL && 2483 !getcanonname(hostbuf, size, TRUE)) 2484 { 2485 sm_syslog(LOG_CRIT, NOQID, 2486 "My unqualified host name (%s) unknown; sleeping for retry", 2487 hostbuf); 2488 message("My unqualified host name (%s) unknown; sleeping for retry", 2489 hostbuf); 2490 (void) sleep(60); 2491 if (!getcanonname(hostbuf, size, TRUE)) 2492 { 2493 sm_syslog(LOG_ALERT, NOQID, 2494 "unable to qualify my own domain name (%s) -- using short name", 2495 hostbuf); 2496 message("WARNING: unable to qualify my own domain name (%s) -- using short name", 2497 hostbuf); 2498 } 2499 } 2500 return hp; 2501 } 2502 /* 2503 ** ADDRCMP -- compare two host addresses 2504 ** 2505 ** Parameters: 2506 ** hp -- hostent structure for the first address 2507 ** ha -- actual first address 2508 ** sa -- second address 2509 ** 2510 ** Returns: 2511 ** 0 -- if ha and sa match 2512 ** else -- they don't match 2513 */ 2514 2515 static int 2516 addrcmp(hp, ha, sa) 2517 struct hostent *hp; 2518 char *ha; 2519 SOCKADDR *sa; 2520 { 2521 # if NETINET6 2522 u_char *a; 2523 # endif /* NETINET6 */ 2524 2525 switch (sa->sa.sa_family) 2526 { 2527 # if NETINET 2528 case AF_INET: 2529 if (hp->h_addrtype == AF_INET) 2530 return memcmp(ha, (char *) &sa->sin.sin_addr, INADDRSZ); 2531 break; 2532 # endif /* NETINET */ 2533 2534 # if NETINET6 2535 case AF_INET6: 2536 a = (u_char *) &sa->sin6.sin6_addr; 2537 2538 /* Straight binary comparison */ 2539 if (hp->h_addrtype == AF_INET6) 2540 return memcmp(ha, a, IN6ADDRSZ); 2541 2542 /* If IPv4-mapped IPv6 address, compare the IPv4 section */ 2543 if (hp->h_addrtype == AF_INET && 2544 IN6_IS_ADDR_V4MAPPED(&sa->sin6.sin6_addr)) 2545 return memcmp(a + IN6ADDRSZ - INADDRSZ, ha, INADDRSZ); 2546 break; 2547 # endif /* NETINET6 */ 2548 } 2549 return -1; 2550 } 2551 /* 2552 ** GETAUTHINFO -- get the real host name associated with a file descriptor 2553 ** 2554 ** Uses RFC1413 protocol to try to get info from the other end. 2555 ** 2556 ** Parameters: 2557 ** fd -- the descriptor 2558 ** may_be_forged -- an outage that is set to TRUE if the 2559 ** forward lookup of RealHostName does not match 2560 ** RealHostAddr; set to FALSE if they do match. 2561 ** 2562 ** Returns: 2563 ** The user@host information associated with this descriptor. 2564 */ 2565 2566 static jmp_buf CtxAuthTimeout; 2567 2568 static void 2569 authtimeout() 2570 { 2571 longjmp(CtxAuthTimeout, 1); 2572 } 2573 2574 char * 2575 getauthinfo(fd, may_be_forged) 2576 int fd; 2577 bool *may_be_forged; 2578 { 2579 volatile u_short port = 0; 2580 SOCKADDR_LEN_T falen; 2581 register char *volatile p = NULL; 2582 SOCKADDR la; 2583 SOCKADDR_LEN_T lalen; 2584 register struct servent *sp; 2585 volatile int s; 2586 int i = 0; 2587 EVENT *ev; 2588 int nleft; 2589 struct hostent *hp; 2590 char *ostype = NULL; 2591 char **ha; 2592 char ibuf[MAXNAME + 1]; 2593 static char hbuf[MAXNAME * 2 + 11]; 2594 2595 *may_be_forged = FALSE; 2596 falen = sizeof RealHostAddr; 2597 if (isatty(fd) || (i = getpeername(fd, &RealHostAddr.sa, &falen)) < 0 || 2598 falen <= 0 || RealHostAddr.sa.sa_family == 0) 2599 { 2600 if (i < 0) 2601 { 2602 /* 2603 ** ENOTSOCK is OK: bail on anything else, but reset 2604 ** errno in this case, so a mis-report doesn't 2605 ** happen later. 2606 */ 2607 if (errno != ENOTSOCK) 2608 return NULL; 2609 errno = 0; 2610 } 2611 (void) snprintf(hbuf, sizeof hbuf, "%s@localhost", 2612 RealUserName); 2613 if (tTd(9, 1)) 2614 dprintf("getauthinfo: %s\n", hbuf); 2615 return hbuf; 2616 } 2617 2618 if (RealHostName == NULL) 2619 { 2620 /* translate that to a host name */ 2621 RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr)); 2622 if (strlen(RealHostName) > MAXNAME) 2623 RealHostName[MAXNAME] = '\0'; 2624 } 2625 2626 /* cross check RealHostName with forward DNS lookup */ 2627 if (anynet_ntoa(&RealHostAddr)[0] == '[' || 2628 RealHostName[0] == '[') 2629 { 2630 /* 2631 ** address is not a socket or have an 2632 ** IP address with no forward lookup 2633 */ 2634 *may_be_forged = FALSE; 2635 } 2636 else 2637 { 2638 /* try to match the reverse against the forward lookup */ 2639 hp = sm_gethostbyname(RealHostName, 2640 RealHostAddr.sa.sa_family); 2641 2642 if (hp == NULL) 2643 *may_be_forged = TRUE; 2644 else 2645 { 2646 for (ha = hp->h_addr_list; *ha != NULL; ha++) 2647 if (addrcmp(hp, *ha, &RealHostAddr) == 0) 2648 break; 2649 *may_be_forged = *ha == NULL; 2650 # if _FFR_FREEHOSTENT && NETINET6 2651 freehostent(hp); 2652 hp = NULL; 2653 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 2654 } 2655 } 2656 2657 if (TimeOuts.to_ident == 0) 2658 goto noident; 2659 2660 lalen = sizeof la; 2661 switch (RealHostAddr.sa.sa_family) 2662 { 2663 # if NETINET 2664 case AF_INET: 2665 if (getsockname(fd, &la.sa, &lalen) < 0 || 2666 lalen <= 0 || 2667 la.sa.sa_family != AF_INET) 2668 { 2669 /* no ident info */ 2670 goto noident; 2671 } 2672 port = RealHostAddr.sin.sin_port; 2673 2674 /* create ident query */ 2675 (void) snprintf(ibuf, sizeof ibuf, "%d,%d\r\n", 2676 ntohs(RealHostAddr.sin.sin_port), 2677 ntohs(la.sin.sin_port)); 2678 2679 /* create local address */ 2680 la.sin.sin_port = 0; 2681 2682 /* create foreign address */ 2683 # ifdef NO_GETSERVBYNAME 2684 RealHostAddr.sin.sin_port = htons(113); 2685 # else /* NO_GETSERVBYNAME */ 2686 sp = getservbyname("auth", "tcp"); 2687 if (sp != NULL) 2688 RealHostAddr.sin.sin_port = sp->s_port; 2689 else 2690 RealHostAddr.sin.sin_port = htons(113); 2691 break; 2692 # endif /* NO_GETSERVBYNAME */ 2693 # endif /* NETINET */ 2694 2695 # if NETINET6 2696 case AF_INET6: 2697 if (getsockname(fd, &la.sa, &lalen) < 0 || 2698 lalen <= 0 || 2699 la.sa.sa_family != AF_INET6) 2700 { 2701 /* no ident info */ 2702 goto noident; 2703 } 2704 port = RealHostAddr.sin6.sin6_port; 2705 2706 /* create ident query */ 2707 (void) snprintf(ibuf, sizeof ibuf, "%d,%d\r\n", 2708 ntohs(RealHostAddr.sin6.sin6_port), 2709 ntohs(la.sin6.sin6_port)); 2710 2711 /* create local address */ 2712 la.sin6.sin6_port = 0; 2713 2714 /* create foreign address */ 2715 # ifdef NO_GETSERVBYNAME 2716 RealHostAddr.sin6.sin6_port = htons(113); 2717 # else /* NO_GETSERVBYNAME */ 2718 sp = getservbyname("auth", "tcp"); 2719 if (sp != NULL) 2720 RealHostAddr.sin6.sin6_port = sp->s_port; 2721 else 2722 RealHostAddr.sin6.sin6_port = htons(113); 2723 break; 2724 # endif /* NO_GETSERVBYNAME */ 2725 # endif /* NETINET6 */ 2726 default: 2727 /* no ident info */ 2728 goto noident; 2729 } 2730 2731 s = -1; 2732 if (setjmp(CtxAuthTimeout) != 0) 2733 { 2734 if (s >= 0) 2735 (void) close(s); 2736 goto noident; 2737 } 2738 2739 /* put a timeout around the whole thing */ 2740 ev = setevent(TimeOuts.to_ident, authtimeout, 0); 2741 2742 2743 /* connect to foreign IDENT server using same address as SMTP socket */ 2744 s = socket(la.sa.sa_family, SOCK_STREAM, 0); 2745 if (s < 0) 2746 { 2747 clrevent(ev); 2748 goto noident; 2749 } 2750 if (bind(s, &la.sa, lalen) < 0 || 2751 connect(s, &RealHostAddr.sa, lalen) < 0) 2752 { 2753 goto closeident; 2754 } 2755 2756 if (tTd(9, 10)) 2757 dprintf("getauthinfo: sent %s", ibuf); 2758 2759 /* send query */ 2760 if (write(s, ibuf, strlen(ibuf)) < 0) 2761 goto closeident; 2762 2763 /* get result */ 2764 p = &ibuf[0]; 2765 nleft = sizeof ibuf - 1; 2766 while ((i = read(s, p, nleft)) > 0) 2767 { 2768 p += i; 2769 nleft -= i; 2770 *p = '\0'; 2771 if (strchr(ibuf, '\n') != NULL) 2772 break; 2773 } 2774 (void) close(s); 2775 clrevent(ev); 2776 if (i < 0 || p == &ibuf[0]) 2777 goto noident; 2778 2779 if (*--p == '\n' && *--p == '\r') 2780 p--; 2781 *++p = '\0'; 2782 2783 if (tTd(9, 3)) 2784 dprintf("getauthinfo: got %s\n", ibuf); 2785 2786 /* parse result */ 2787 p = strchr(ibuf, ':'); 2788 if (p == NULL) 2789 { 2790 /* malformed response */ 2791 goto noident; 2792 } 2793 while (isascii(*++p) && isspace(*p)) 2794 continue; 2795 if (strncasecmp(p, "userid", 6) != 0) 2796 { 2797 /* presumably an error string */ 2798 goto noident; 2799 } 2800 p += 6; 2801 while (isascii(*p) && isspace(*p)) 2802 p++; 2803 if (*p++ != ':') 2804 { 2805 /* either useridxx or malformed response */ 2806 goto noident; 2807 } 2808 2809 /* p now points to the OSTYPE field */ 2810 while (isascii(*p) && isspace(*p)) 2811 p++; 2812 ostype = p; 2813 p = strchr(p, ':'); 2814 if (p == NULL) 2815 { 2816 /* malformed response */ 2817 goto noident; 2818 } 2819 else 2820 { 2821 char *charset; 2822 2823 *p = '\0'; 2824 charset = strchr(ostype, ','); 2825 if (charset != NULL) 2826 *charset = '\0'; 2827 } 2828 2829 /* 1413 says don't do this -- but it's broken otherwise */ 2830 while (isascii(*++p) && isspace(*p)) 2831 continue; 2832 2833 /* p now points to the authenticated name -- copy carefully */ 2834 if (strncasecmp(ostype, "other", 5) == 0 && 2835 (ostype[5] == ' ' || ostype[5] == '\0')) 2836 { 2837 snprintf(hbuf, sizeof hbuf, "IDENT:"); 2838 cleanstrcpy(&hbuf[6], p, MAXNAME); 2839 } 2840 else 2841 cleanstrcpy(hbuf, p, MAXNAME); 2842 i = strlen(hbuf); 2843 snprintf(&hbuf[i], sizeof hbuf - i, "@%s", 2844 RealHostName == NULL ? "localhost" : RealHostName); 2845 goto postident; 2846 2847 closeident: 2848 (void) close(s); 2849 clrevent(ev); 2850 2851 noident: 2852 /* put back the original incoming port */ 2853 switch (RealHostAddr.sa.sa_family) 2854 { 2855 # if NETINET 2856 case AF_INET: 2857 if (port > 0) 2858 RealHostAddr.sin.sin_port = port; 2859 break; 2860 # endif /* NETINET */ 2861 2862 # if NETINET6 2863 case AF_INET6: 2864 if (port > 0) 2865 RealHostAddr.sin6.sin6_port = port; 2866 break; 2867 # endif /* NETINET6 */ 2868 } 2869 2870 if (RealHostName == NULL) 2871 { 2872 if (tTd(9, 1)) 2873 dprintf("getauthinfo: NULL\n"); 2874 return NULL; 2875 } 2876 snprintf(hbuf, sizeof hbuf, "%s", RealHostName); 2877 2878 postident: 2879 # if IP_SRCROUTE 2880 # ifndef GET_IPOPT_DST 2881 # define GET_IPOPT_DST(dst) (dst) 2882 # endif /* ! GET_IPOPT_DST */ 2883 /* 2884 ** Extract IP source routing information. 2885 ** 2886 ** Format of output for a connection from site a through b 2887 ** through c to d: 2888 ** loose: @site-c@site-b:site-a 2889 ** strict: !@site-c@site-b:site-a 2890 ** 2891 ** o - pointer within ipopt_list structure. 2892 ** q - pointer within ls/ss rr route data 2893 ** p - pointer to hbuf 2894 */ 2895 2896 if (RealHostAddr.sa.sa_family == AF_INET) 2897 { 2898 SOCKOPT_LEN_T ipoptlen; 2899 int j; 2900 u_char *q; 2901 u_char *o; 2902 int l; 2903 struct IPOPTION ipopt; 2904 2905 ipoptlen = sizeof ipopt; 2906 if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS, 2907 (char *) &ipopt, &ipoptlen) < 0) 2908 goto noipsr; 2909 if (ipoptlen == 0) 2910 goto noipsr; 2911 o = (u_char *) ipopt.IP_LIST; 2912 while (o != NULL && o < (u_char *) &ipopt + ipoptlen) 2913 { 2914 switch (*o) 2915 { 2916 case IPOPT_EOL: 2917 o = NULL; 2918 break; 2919 2920 case IPOPT_NOP: 2921 o++; 2922 break; 2923 2924 case IPOPT_SSRR: 2925 case IPOPT_LSRR: 2926 /* 2927 ** Source routing. 2928 ** o[0] is the option type (loose/strict). 2929 ** o[1] is the length of this option, 2930 ** including option type and 2931 ** length. 2932 ** o[2] is the pointer into the route 2933 ** data. 2934 ** o[3] begins the route data. 2935 */ 2936 2937 p = &hbuf[strlen(hbuf)]; 2938 l = sizeof hbuf - (hbuf - p) - 6; 2939 snprintf(p, SPACELEFT(hbuf, p), " [%s@%.*s", 2940 *o == IPOPT_SSRR ? "!" : "", 2941 l > 240 ? 120 : l / 2, 2942 inet_ntoa(GET_IPOPT_DST(ipopt.IP_DST))); 2943 i = strlen(p); 2944 p += i; 2945 l -= strlen(p); 2946 2947 j = o[1] / sizeof(struct in_addr) - 1; 2948 2949 /* q skips length and router pointer to data */ 2950 q = &o[3]; 2951 for ( ; j >= 0; j--) 2952 { 2953 struct in_addr addr; 2954 2955 memcpy(&addr, q, sizeof(addr)); 2956 snprintf(p, SPACELEFT(hbuf, p), 2957 "%c%.*s", 2958 j != 0 ? '@' : ':', 2959 l > 240 ? 120 : 2960 j == 0 ? l : l / 2, 2961 inet_ntoa(addr)); 2962 i = strlen(p); 2963 p += i; 2964 l -= i + 1; 2965 q += sizeof(struct in_addr); 2966 } 2967 o += o[1]; 2968 break; 2969 2970 default: 2971 /* Skip over option */ 2972 o += o[1]; 2973 break; 2974 } 2975 } 2976 snprintf(p, SPACELEFT(hbuf, p), "]"); 2977 goto postipsr; 2978 } 2979 2980 noipsr: 2981 # endif /* IP_SRCROUTE */ 2982 if (RealHostName != NULL && RealHostName[0] != '[') 2983 { 2984 p = &hbuf[strlen(hbuf)]; 2985 (void) snprintf(p, SPACELEFT(hbuf, p), " [%.100s]", 2986 anynet_ntoa(&RealHostAddr)); 2987 } 2988 if (*may_be_forged) 2989 { 2990 p = &hbuf[strlen(hbuf)]; 2991 (void) snprintf(p, SPACELEFT(hbuf, p), " (may be forged)"); 2992 } 2993 2994 # if IP_SRCROUTE 2995 postipsr: 2996 # endif /* IP_SRCROUTE */ 2997 if (tTd(9, 1)) 2998 dprintf("getauthinfo: %s\n", hbuf); 2999 3000 /* put back the original incoming port */ 3001 switch (RealHostAddr.sa.sa_family) 3002 { 3003 # if NETINET 3004 case AF_INET: 3005 if (port > 0) 3006 RealHostAddr.sin.sin_port = port; 3007 break; 3008 # endif /* NETINET */ 3009 3010 # if NETINET6 3011 case AF_INET6: 3012 if (port > 0) 3013 RealHostAddr.sin6.sin6_port = port; 3014 break; 3015 # endif /* NETINET6 */ 3016 } 3017 3018 return hbuf; 3019 } 3020 /* 3021 ** HOST_MAP_LOOKUP -- turn a hostname into canonical form 3022 ** 3023 ** Parameters: 3024 ** map -- a pointer to this map. 3025 ** name -- the (presumably unqualified) hostname. 3026 ** av -- unused -- for compatibility with other mapping 3027 ** functions. 3028 ** statp -- an exit status (out parameter) -- set to 3029 ** EX_TEMPFAIL if the name server is unavailable. 3030 ** 3031 ** Returns: 3032 ** The mapping, if found. 3033 ** NULL if no mapping found. 3034 ** 3035 ** Side Effects: 3036 ** Looks up the host specified in hbuf. If it is not 3037 ** the canonical name for that host, return the canonical 3038 ** name (unless MF_MATCHONLY is set, which will cause the 3039 ** status only to be returned). 3040 */ 3041 3042 char * 3043 host_map_lookup(map, name, av, statp) 3044 MAP *map; 3045 char *name; 3046 char **av; 3047 int *statp; 3048 { 3049 register struct hostent *hp; 3050 # if NETINET 3051 struct in_addr in_addr; 3052 # endif /* NETINET */ 3053 # if NETINET6 3054 struct in6_addr in6_addr; 3055 # endif /* NETINET6 */ 3056 char *cp, *ans = NULL; 3057 register STAB *s; 3058 char hbuf[MAXNAME + 1]; 3059 3060 /* 3061 ** See if we have already looked up this name. If so, just 3062 ** return it. 3063 */ 3064 3065 s = stab(name, ST_NAMECANON, ST_ENTER); 3066 if (bitset(NCF_VALID, s->s_namecanon.nc_flags)) 3067 { 3068 if (tTd(9, 1)) 3069 dprintf("host_map_lookup(%s) => CACHE %s\n", 3070 name, 3071 s->s_namecanon.nc_cname == NULL 3072 ? "NULL" 3073 : s->s_namecanon.nc_cname); 3074 errno = s->s_namecanon.nc_errno; 3075 # if NAMED_BIND 3076 SM_SET_H_ERRNO(s->s_namecanon.nc_herrno); 3077 # endif /* NAMED_BIND */ 3078 *statp = s->s_namecanon.nc_stat; 3079 if (*statp == EX_TEMPFAIL) 3080 { 3081 CurEnv->e_status = "4.4.3"; 3082 message("851 %s: Name server timeout", 3083 shortenstring(name, 33)); 3084 } 3085 if (*statp != EX_OK) 3086 return NULL; 3087 if (s->s_namecanon.nc_cname == NULL) 3088 { 3089 syserr("host_map_lookup(%s): bogus NULL cache entry, errno = %d, h_errno = %d", 3090 name, 3091 s->s_namecanon.nc_errno, 3092 s->s_namecanon.nc_herrno); 3093 return NULL; 3094 } 3095 if (bitset(MF_MATCHONLY, map->map_mflags)) 3096 cp = map_rewrite(map, name, strlen(name), NULL); 3097 else 3098 cp = map_rewrite(map, 3099 s->s_namecanon.nc_cname, 3100 strlen(s->s_namecanon.nc_cname), 3101 av); 3102 return cp; 3103 } 3104 3105 /* 3106 ** If we are running without a regular network connection (usually 3107 ** dial-on-demand) and we are just queueing, we want to avoid DNS 3108 ** lookups because those could try to connect to a server. 3109 */ 3110 3111 if (CurEnv->e_sendmode == SM_DEFER && 3112 bitset(MF_DEFER, map->map_mflags)) 3113 { 3114 if (tTd(9, 1)) 3115 dprintf("host_map_lookup(%s) => DEFERRED\n", name); 3116 *statp = EX_TEMPFAIL; 3117 return NULL; 3118 } 3119 3120 /* 3121 ** If first character is a bracket, then it is an address 3122 ** lookup. Address is copied into a temporary buffer to 3123 ** strip the brackets and to preserve name if address is 3124 ** unknown. 3125 */ 3126 3127 if (tTd(9, 1)) 3128 dprintf("host_map_lookup(%s) => ", name); 3129 if (*name != '[') 3130 { 3131 snprintf(hbuf, sizeof hbuf, "%s", name); 3132 if (getcanonname(hbuf, sizeof hbuf - 1, !HasWildcardMX)) 3133 ans = hbuf; 3134 } 3135 else 3136 { 3137 if ((cp = strchr(name, ']')) == NULL) 3138 { 3139 if (tTd(9, 1)) 3140 dprintf("FAILED\n"); 3141 return NULL; 3142 } 3143 *cp = '\0'; 3144 3145 hp = NULL; 3146 # if NETINET 3147 if ((in_addr.s_addr = inet_addr(&name[1])) != INADDR_NONE) 3148 hp = sm_gethostbyaddr((char *)&in_addr, 3149 INADDRSZ, AF_INET); 3150 # endif /* NETINET */ 3151 # if NETINET6 3152 if (hp == NULL && 3153 inet_pton(AF_INET6, &name[1], &in6_addr) == 1) 3154 hp = sm_gethostbyaddr((char *)&in6_addr, 3155 IN6ADDRSZ, AF_INET6); 3156 # endif /* NETINET6 */ 3157 *cp = ']'; 3158 3159 if (hp != NULL) 3160 { 3161 /* found a match -- copy out */ 3162 ans = denlstring((char *) hp->h_name, TRUE, TRUE); 3163 # if _FFR_FREEHOSTENT && NETINET6 3164 freehostent(hp); 3165 hp = NULL; 3166 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 3167 } 3168 } 3169 3170 s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */ 3171 3172 /* Found an answer */ 3173 if (ans != NULL) 3174 { 3175 s->s_namecanon.nc_stat = *statp = EX_OK; 3176 s->s_namecanon.nc_cname = newstr(ans); 3177 if (bitset(MF_MATCHONLY, map->map_mflags)) 3178 cp = map_rewrite(map, name, strlen(name), NULL); 3179 else 3180 cp = map_rewrite(map, ans, strlen(ans), av); 3181 if (tTd(9, 1)) 3182 dprintf("FOUND %s\n", ans); 3183 return cp; 3184 } 3185 3186 3187 /* No match found */ 3188 s->s_namecanon.nc_errno = errno; 3189 # if NAMED_BIND 3190 s->s_namecanon.nc_herrno = h_errno; 3191 if (tTd(9, 1)) 3192 dprintf("FAIL (%d)\n", h_errno); 3193 switch (h_errno) 3194 { 3195 case TRY_AGAIN: 3196 if (UseNameServer) 3197 { 3198 CurEnv->e_status = "4.4.3"; 3199 message("851 %s: Name server timeout", 3200 shortenstring(name, 33)); 3201 } 3202 *statp = EX_TEMPFAIL; 3203 break; 3204 3205 case HOST_NOT_FOUND: 3206 case NO_DATA: 3207 *statp = EX_NOHOST; 3208 break; 3209 3210 case NO_RECOVERY: 3211 *statp = EX_SOFTWARE; 3212 break; 3213 3214 default: 3215 *statp = EX_UNAVAILABLE; 3216 break; 3217 } 3218 # else /* NAMED_BIND */ 3219 if (tTd(9, 1)) 3220 dprintf("FAIL\n"); 3221 *statp = EX_NOHOST; 3222 # endif /* NAMED_BIND */ 3223 s->s_namecanon.nc_stat = *statp; 3224 return NULL; 3225 } 3226 #else /* DAEMON */ 3227 /* code for systems without sophisticated networking */ 3228 3229 /* 3230 ** MYHOSTNAME -- stub version for case of no daemon code. 3231 ** 3232 ** Can't convert to upper case here because might be a UUCP name. 3233 ** 3234 ** Mark, you can change this to be anything you want...... 3235 */ 3236 3237 char ** 3238 myhostname(hostbuf, size) 3239 char hostbuf[]; 3240 int size; 3241 { 3242 register FILE *f; 3243 3244 hostbuf[0] = '\0'; 3245 f = fopen("/usr/include/whoami", "r"); 3246 if (f != NULL) 3247 { 3248 (void) fgets(hostbuf, size, f); 3249 fixcrlf(hostbuf, TRUE); 3250 (void) fclose(f); 3251 } 3252 if (hostbuf[0] == '\0') 3253 (void) strlcpy(hostbuf, "localhost", size); 3254 return NULL; 3255 } 3256 /* 3257 ** GETAUTHINFO -- get the real host name associated with a file descriptor 3258 ** 3259 ** Parameters: 3260 ** fd -- the descriptor 3261 ** may_be_forged -- an outage that is set to TRUE if the 3262 ** forward lookup of RealHostName does not match 3263 ** RealHostAddr; set to FALSE if they do match. 3264 ** 3265 ** Returns: 3266 ** The host name associated with this descriptor, if it can 3267 ** be determined. 3268 ** NULL otherwise. 3269 ** 3270 ** Side Effects: 3271 ** none 3272 */ 3273 3274 char * 3275 getauthinfo(fd, may_be_forged) 3276 int fd; 3277 bool *may_be_forged; 3278 { 3279 *may_be_forged = FALSE; 3280 return NULL; 3281 } 3282 /* 3283 ** HOST_MAP_LOOKUP -- turn a hostname into canonical form 3284 ** 3285 ** Parameters: 3286 ** map -- a pointer to the database map. 3287 ** name -- a buffer containing a hostname. 3288 ** avp -- a pointer to a (cf file defined) argument vector. 3289 ** statp -- an exit status (out parameter). 3290 ** 3291 ** Returns: 3292 ** mapped host name 3293 ** FALSE otherwise. 3294 ** 3295 ** Side Effects: 3296 ** Looks up the host specified in name. If it is not 3297 ** the canonical name for that host, replace it with 3298 ** the canonical name. If the name is unknown, or it 3299 ** is already the canonical name, leave it unchanged. 3300 */ 3301 3302 /*ARGSUSED*/ 3303 char * 3304 host_map_lookup(map, name, avp, statp) 3305 MAP *map; 3306 char *name; 3307 char **avp; 3308 char *statp; 3309 { 3310 register struct hostent *hp = NULL; 3311 char *cp; 3312 3313 hp = sm_gethostbyname(name, InetMode); 3314 if (hp == NULL && InetMode != AF_INET) 3315 hp = sm_gethostbyname(name, AF_INET); 3316 if (hp == NULL) 3317 { 3318 # if NAMED_BIND 3319 if (tTd(9, 1)) 3320 dprintf("FAIL (%d)\n", h_errno); 3321 switch (h_errno) 3322 { 3323 case TRY_AGAIN: 3324 if (UseNameServer) 3325 { 3326 CurEnv->e_status = "4.4.3"; 3327 message("851 %s: Name server timeout", 3328 shortenstring(name, 33)); 3329 } 3330 *statp = EX_TEMPFAIL; 3331 break; 3332 3333 case HOST_NOT_FOUND: 3334 case NO_DATA: 3335 *statp = EX_NOHOST; 3336 break; 3337 3338 case NO_RECOVERY: 3339 *statp = EX_SOFTWARE; 3340 break; 3341 3342 default: 3343 *statp = EX_UNAVAILABLE; 3344 break; 3345 } 3346 #else /* NAMED_BIND */ 3347 *statp = EX_NOHOST; 3348 #endif /* NAMED_BIND */ 3349 return NULL; 3350 } 3351 if (bitset(MF_MATCHONLY, map->map_mflags)) 3352 cp = map_rewrite(map, name, strlen(name), NULL); 3353 else 3354 cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), avp); 3355 # if _FFR_FREEHOSTENT && NETINET6 3356 freehostent(hp); 3357 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 3358 return cp; 3359 } 3360 3361 #endif /* DAEMON */ 3362 /* 3363 ** HOST_MAP_INIT -- initialize host class structures 3364 */ 3365 3366 bool 3367 host_map_init(map, args) 3368 MAP *map; 3369 char *args; 3370 { 3371 register char *p = args; 3372 3373 for (;;) 3374 { 3375 while (isascii(*p) && isspace(*p)) 3376 p++; 3377 if (*p != '-') 3378 break; 3379 switch (*++p) 3380 { 3381 case 'a': 3382 map->map_app = ++p; 3383 break; 3384 3385 case 'T': 3386 map->map_tapp = ++p; 3387 break; 3388 3389 case 'm': 3390 map->map_mflags |= MF_MATCHONLY; 3391 break; 3392 3393 case 't': 3394 map->map_mflags |= MF_NODEFER; 3395 break; 3396 3397 case 'S': /* only for consistency */ 3398 map->map_spacesub = *++p; 3399 break; 3400 3401 case 'D': 3402 map->map_mflags |= MF_DEFER; 3403 break; 3404 } 3405 while (*p != '\0' && !(isascii(*p) && isspace(*p))) 3406 p++; 3407 if (*p != '\0') 3408 *p++ = '\0'; 3409 } 3410 if (map->map_app != NULL) 3411 map->map_app = newstr(map->map_app); 3412 if (map->map_tapp != NULL) 3413 map->map_tapp = newstr(map->map_tapp); 3414 return TRUE; 3415 } 3416 3417 #if NETINET6 3418 /* 3419 ** ANYNET_NTOP -- convert an IPv6 network address to printable form. 3420 ** 3421 ** Parameters: 3422 ** s6a -- a pointer to an in6_addr structure. 3423 ** dst -- buffer to store result in 3424 ** dst_len -- size of dst buffer 3425 ** 3426 ** Returns: 3427 ** A printable version of that structure. 3428 */ 3429 char * 3430 anynet_ntop(s6a, dst, dst_len) 3431 struct in6_addr *s6a; 3432 char *dst; 3433 size_t dst_len; 3434 { 3435 register char *ap; 3436 3437 if (IN6_IS_ADDR_V4MAPPED(s6a)) 3438 ap = (char *) inet_ntop(AF_INET, 3439 &s6a->s6_addr[IN6ADDRSZ - INADDRSZ], 3440 dst, dst_len); 3441 else 3442 ap = (char *) inet_ntop(AF_INET6, s6a, dst, dst_len); 3443 return ap; 3444 } 3445 #endif /* NETINET6 */ 3446 /* 3447 ** ANYNET_NTOA -- convert a network address to printable form. 3448 ** 3449 ** Parameters: 3450 ** sap -- a pointer to a sockaddr structure. 3451 ** 3452 ** Returns: 3453 ** A printable version of that sockaddr. 3454 */ 3455 3456 #ifdef USE_SOCK_STREAM 3457 3458 # if NETLINK 3459 # include <net/if_dl.h> 3460 # endif /* NETLINK */ 3461 3462 char * 3463 anynet_ntoa(sap) 3464 register SOCKADDR *sap; 3465 { 3466 register char *bp; 3467 register char *ap; 3468 int l; 3469 static char buf[100]; 3470 3471 /* check for null/zero family */ 3472 if (sap == NULL) 3473 return "NULLADDR"; 3474 if (sap->sa.sa_family == 0) 3475 return "0"; 3476 3477 switch (sap->sa.sa_family) 3478 { 3479 # if NETUNIX 3480 case AF_UNIX: 3481 if (sap->sunix.sun_path[0] != '\0') 3482 snprintf(buf, sizeof buf, "[UNIX: %.64s]", 3483 sap->sunix.sun_path); 3484 else 3485 snprintf(buf, sizeof buf, "[UNIX: localhost]"); 3486 return buf; 3487 # endif /* NETUNIX */ 3488 3489 # if NETINET 3490 case AF_INET: 3491 return (char *) inet_ntoa(sap->sin.sin_addr); 3492 # endif /* NETINET */ 3493 3494 # if NETINET6 3495 case AF_INET6: 3496 ap = anynet_ntop(&sap->sin6.sin6_addr, buf, sizeof buf); 3497 if (ap != NULL) 3498 return ap; 3499 break; 3500 # endif /* NETINET6 */ 3501 3502 # if NETLINK 3503 case AF_LINK: 3504 snprintf(buf, sizeof buf, "[LINK: %s]", 3505 link_ntoa((struct sockaddr_dl *) &sap->sa)); 3506 return buf; 3507 # endif /* NETLINK */ 3508 default: 3509 /* this case is needed when nothing is #defined */ 3510 /* in order to keep the switch syntactically correct */ 3511 break; 3512 } 3513 3514 /* unknown family -- just dump bytes */ 3515 (void) snprintf(buf, sizeof buf, "Family %d: ", sap->sa.sa_family); 3516 bp = &buf[strlen(buf)]; 3517 ap = sap->sa.sa_data; 3518 for (l = sizeof sap->sa.sa_data; --l >= 0; ) 3519 { 3520 (void) snprintf(bp, SPACELEFT(buf, bp), "%02x:", *ap++ & 0377); 3521 bp += 3; 3522 } 3523 *--bp = '\0'; 3524 return buf; 3525 } 3526 /* 3527 ** HOSTNAMEBYANYADDR -- return name of host based on address 3528 ** 3529 ** Parameters: 3530 ** sap -- SOCKADDR pointer 3531 ** 3532 ** Returns: 3533 ** text representation of host name. 3534 ** 3535 ** Side Effects: 3536 ** none. 3537 */ 3538 3539 char * 3540 hostnamebyanyaddr(sap) 3541 register SOCKADDR *sap; 3542 { 3543 register struct hostent *hp; 3544 # if NAMED_BIND 3545 int saveretry; 3546 # endif /* NAMED_BIND */ 3547 # if NETINET6 3548 struct in6_addr in6_addr; 3549 # endif /* NETINET6 */ 3550 3551 # if NAMED_BIND 3552 /* shorten name server timeout to avoid higher level timeouts */ 3553 saveretry = _res.retry; 3554 if (_res.retry * _res.retrans > 20) 3555 _res.retry = 20 / _res.retrans; 3556 # endif /* NAMED_BIND */ 3557 3558 switch (sap->sa.sa_family) 3559 { 3560 # if NETINET 3561 case AF_INET: 3562 hp = sm_gethostbyaddr((char *) &sap->sin.sin_addr, 3563 INADDRSZ, 3564 AF_INET); 3565 break; 3566 # endif /* NETINET */ 3567 3568 # if NETINET6 3569 case AF_INET6: 3570 hp = sm_gethostbyaddr((char *) &sap->sin6.sin6_addr, 3571 IN6ADDRSZ, 3572 AF_INET6); 3573 break; 3574 # endif /* NETINET6 */ 3575 3576 # if NETISO 3577 case AF_ISO: 3578 hp = sm_gethostbyaddr((char *) &sap->siso.siso_addr, 3579 sizeof sap->siso.siso_addr, 3580 AF_ISO); 3581 break; 3582 # endif /* NETISO */ 3583 3584 # if NETUNIX 3585 case AF_UNIX: 3586 hp = NULL; 3587 break; 3588 # endif /* NETUNIX */ 3589 3590 default: 3591 hp = sm_gethostbyaddr(sap->sa.sa_data, 3592 sizeof sap->sa.sa_data, 3593 sap->sa.sa_family); 3594 break; 3595 } 3596 3597 # if NAMED_BIND 3598 _res.retry = saveretry; 3599 # endif /* NAMED_BIND */ 3600 3601 # if NETINET || NETINET6 3602 if (hp != NULL && hp->h_name[0] != '[' 3603 # if NETINET6 3604 && inet_pton(AF_INET6, hp->h_name, &in6_addr) != 1 3605 # endif /* NETINET6 */ 3606 # if NETINET 3607 && inet_addr(hp->h_name) == INADDR_NONE 3608 # endif /* NETINET */ 3609 ) 3610 { 3611 char *name; 3612 3613 name = denlstring((char *) hp->h_name, TRUE, TRUE); 3614 3615 # if _FFR_FREEHOSTENT && NETINET6 3616 if (name == hp->h_name) 3617 { 3618 static char n[MAXNAME + 1]; 3619 3620 /* Copy the string, hp->h_name is about to disappear */ 3621 strlcpy(n, name, sizeof n); 3622 name = n; 3623 } 3624 3625 freehostent(hp); 3626 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 3627 return name; 3628 } 3629 # endif /* NETINET || NETINET6 */ 3630 3631 # if _FFR_FREEHOSTENT && NETINET6 3632 if (hp != NULL) 3633 { 3634 freehostent(hp); 3635 hp = NULL; 3636 } 3637 # endif /* _FFR_FREEHOSTENT && NETINET6 */ 3638 3639 # if NETUNIX 3640 if (sap->sa.sa_family == AF_UNIX && sap->sunix.sun_path[0] == '\0') 3641 return "localhost"; 3642 # endif /* NETUNIX */ 3643 { 3644 static char buf[203]; 3645 3646 (void) snprintf(buf, sizeof buf, "[%.200s]", anynet_ntoa(sap)); 3647 return buf; 3648 } 3649 } 3650 #endif /* USE_SOCK_STREAM */ 3651