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