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 8.613 2002/06/05 21:26:35 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 struct dflags 1714 { 1715 char *d_name; 1716 int d_flag; 1717 }; 1718 1719 static struct dflags DaemonFlags[] = 1720 { 1721 { "AUTHREQ", D_AUTHREQ }, 1722 { "BINDIF", D_BINDIF }, 1723 { "CANONREQ", D_CANONREQ }, 1724 { "IFNHELO", D_IFNHELO }, 1725 { "FQMAIL", D_FQMAIL }, 1726 { "FQRCPT", D_FQRCPT }, 1727 #if _FFR_SMTP_SSL 1728 { "SMTPS", D_SMTPS }, 1729 #endif /* _FFR_SMTP_SSL */ 1730 { "UNQUALOK", D_UNQUALOK }, 1731 { "NOAUTH", D_NOAUTH }, 1732 { "NOCANON", D_NOCANON }, 1733 { "NOETRN", D_NOETRN }, 1734 { "NOTLS", D_NOTLS }, 1735 { "ETRNONLY", D_ETRNONLY }, 1736 { "OPTIONAL", D_OPTIONAL }, 1737 { "DISABLE", D_DISABLE }, 1738 { "ISSET", D_ISSET }, 1739 { NULL, 0 } 1740 }; 1741 1742 static void 1743 printdaemonflags(d) 1744 DAEMON_T *d; 1745 { 1746 register struct dflags *df; 1747 bool first = true; 1748 1749 for (df = DaemonFlags; df->d_name != NULL; df++) 1750 { 1751 if (!bitnset(df->d_flag, d->d_flags)) 1752 continue; 1753 if (first) 1754 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "<%s", 1755 df->d_name); 1756 else 1757 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, ",%s", 1758 df->d_name); 1759 first = false; 1760 } 1761 if (!first) 1762 (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, ">"); 1763 } 1764 1765 bool 1766 setdaemonoptions(p) 1767 register char *p; 1768 { 1769 if (NDaemons >= MAXDAEMONS) 1770 return false; 1771 Daemons[NDaemons].d_socket = -1; 1772 Daemons[NDaemons].d_listenqueue = DEF_LISTENQUEUE; 1773 clrbitmap(Daemons[NDaemons].d_flags); 1774 setsockaddroptions(p, &Daemons[NDaemons]); 1775 1776 #if MILTER 1777 # if _FFR_MILTER_PERDAEMON 1778 if (Daemons[NDaemons].d_inputfilterlist != NULL) 1779 Daemons[NDaemons].d_inputfilterlist = newstr(Daemons[NDaemons].d_inputfilterlist); 1780 # endif /* _FFR_MILTER_PERDAEMON */ 1781 #endif /* MILTER */ 1782 1783 if (Daemons[NDaemons].d_name != NULL) 1784 Daemons[NDaemons].d_name = newstr(Daemons[NDaemons].d_name); 1785 else 1786 { 1787 char num[30]; 1788 1789 (void) sm_snprintf(num, sizeof num, "Daemon%d", NDaemons); 1790 Daemons[NDaemons].d_name = newstr(num); 1791 } 1792 1793 if (tTd(37, 1)) 1794 { 1795 sm_dprintf("Daemon %s flags: ", Daemons[NDaemons].d_name); 1796 printdaemonflags(&Daemons[NDaemons]); 1797 sm_dprintf("\n"); 1798 } 1799 ++NDaemons; 1800 return true; 1801 } 1802 /* 1803 ** INITDAEMON -- initialize daemon if not yet done. 1804 ** 1805 ** Parameters: 1806 ** none 1807 ** 1808 ** Returns: 1809 ** none 1810 ** 1811 ** Side Effects: 1812 ** initializes structure for one daemon. 1813 */ 1814 1815 void 1816 initdaemon() 1817 { 1818 if (NDaemons == 0) 1819 { 1820 Daemons[NDaemons].d_socket = -1; 1821 Daemons[NDaemons].d_listenqueue = DEF_LISTENQUEUE; 1822 Daemons[NDaemons].d_name = "Daemon0"; 1823 NDaemons = 1; 1824 } 1825 } 1826 /* 1827 ** SETCLIENTOPTIONS -- set options for running the client 1828 ** 1829 ** Parameters: 1830 ** p -- the options line. 1831 ** 1832 ** Returns: 1833 ** none. 1834 */ 1835 1836 static DAEMON_T ClientSettings[AF_MAX + 1]; 1837 1838 void 1839 setclientoptions(p) 1840 register char *p; 1841 { 1842 int family; 1843 DAEMON_T d; 1844 1845 memset(&d, '\0', sizeof d); 1846 setsockaddroptions(p, &d); 1847 1848 /* grab what we need */ 1849 family = d.d_addr.sa.sa_family; 1850 STRUCTCOPY(d, ClientSettings[family]); 1851 setbitn(D_ISSET, ClientSettings[family].d_flags); /* mark as set */ 1852 if (d.d_name != NULL) 1853 ClientSettings[family].d_name = newstr(d.d_name); 1854 else 1855 { 1856 char num[30]; 1857 1858 (void) sm_snprintf(num, sizeof num, "Client%d", family); 1859 ClientSettings[family].d_name = newstr(num); 1860 } 1861 } 1862 /* 1863 ** ADDR_FAMILY -- determine address family from address 1864 ** 1865 ** Parameters: 1866 ** addr -- the string representation of the address 1867 ** 1868 ** Returns: 1869 ** AF_INET, AF_INET6 or AF_UNSPEC 1870 ** 1871 ** Side Effects: 1872 ** none. 1873 */ 1874 1875 static int 1876 addr_family(addr) 1877 char *addr; 1878 { 1879 #if NETINET6 1880 SOCKADDR clt_addr; 1881 #endif /* NETINET6 */ 1882 1883 #if NETINET 1884 if (inet_addr(addr) != INADDR_NONE) 1885 { 1886 if (tTd(16, 9)) 1887 sm_dprintf("addr_family(%s): INET\n", addr); 1888 return AF_INET; 1889 } 1890 #endif /* NETINET */ 1891 #if NETINET6 1892 if (anynet_pton(AF_INET6, addr, &clt_addr.sin6.sin6_addr) == 1) 1893 { 1894 if (tTd(16, 9)) 1895 sm_dprintf("addr_family(%s): INET6\n", addr); 1896 return AF_INET6; 1897 } 1898 #endif /* NETINET6 */ 1899 #if _FFR_DAEMON_NETUNIX 1900 # if NETUNIX 1901 if (*addr == '/') 1902 { 1903 if (tTd(16, 9)) 1904 sm_dprintf("addr_family(%s): LOCAL\n", addr); 1905 return AF_UNIX; 1906 } 1907 # endif /* NETUNIX */ 1908 #endif /* _FFR_DAEMON_NETUNIX */ 1909 if (tTd(16, 9)) 1910 sm_dprintf("addr_family(%s): UNSPEC\n", addr); 1911 return AF_UNSPEC; 1912 } 1913 1914 /* 1915 ** CHKCLIENTMODIFIERS -- check whether all clients have set a flag. 1916 ** 1917 ** Parameters: 1918 ** flag -- the flag to test. 1919 ** 1920 ** Returns: 1921 ** true iff all configured clients have set the flag. 1922 */ 1923 1924 bool 1925 chkclientmodifiers(flag) 1926 int flag; 1927 { 1928 int i; 1929 bool flagisset; 1930 1931 flagisset = false; 1932 for (i = 0; i < AF_MAX; i++) 1933 { 1934 if (bitnset(D_ISSET, ClientSettings[i].d_flags)) 1935 { 1936 if (!bitnset((char) flag, ClientSettings[i].d_flags)) 1937 return false; 1938 flagisset = true; 1939 } 1940 } 1941 return flagisset; 1942 } 1943 1944 #if MILTER 1945 # if _FFR_MILTER_PERDAEMON 1946 /* 1947 ** SETUP_DAEMON_FILTERS -- Parse per-socket filters 1948 ** 1949 ** Parameters: 1950 ** none 1951 ** 1952 ** Returns: 1953 ** none 1954 */ 1955 1956 void 1957 setup_daemon_milters() 1958 { 1959 int idx; 1960 1961 if (OpMode == MD_SMTP) 1962 { 1963 /* no need to configure the daemons */ 1964 return; 1965 } 1966 1967 for (idx = 0; idx < NDaemons; idx++) 1968 { 1969 if (Daemons[idx].d_inputfilterlist != NULL) 1970 { 1971 milter_config(Daemons[idx].d_inputfilterlist, 1972 Daemons[idx].d_inputfilters, 1973 MAXFILTERS); 1974 } 1975 } 1976 } 1977 # endif /* _FFR_MILTER_PERDAEMON */ 1978 #endif /* MILTER */ 1979 /* 1980 ** MAKECONNECTION -- make a connection to an SMTP socket on a machine. 1981 ** 1982 ** Parameters: 1983 ** host -- the name of the host. 1984 ** port -- the port number to connect to. 1985 ** mci -- a pointer to the mail connection information 1986 ** structure to be filled in. 1987 ** e -- the current envelope. 1988 ** enough -- time at which to stop further connection attempts. 1989 ** (0 means no limit) 1990 ** 1991 ** Returns: 1992 ** An exit code telling whether the connection could be 1993 ** made and if not why not. 1994 ** 1995 ** Side Effects: 1996 ** none. 1997 */ 1998 1999 static jmp_buf CtxConnectTimeout; 2000 2001 SOCKADDR CurHostAddr; /* address of current host */ 2002 2003 int 2004 makeconnection(host, port, mci, e, enough) 2005 char *host; 2006 volatile unsigned int port; 2007 register MCI *mci; 2008 ENVELOPE *e; 2009 time_t enough; 2010 { 2011 register volatile int addrno = 0; 2012 volatile int s; 2013 register struct hostent *volatile hp = (struct hostent *) NULL; 2014 SOCKADDR addr; 2015 SOCKADDR clt_addr; 2016 int save_errno = 0; 2017 volatile SOCKADDR_LEN_T addrlen; 2018 volatile bool firstconnect; 2019 SM_EVENT *volatile ev = NULL; 2020 #if NETINET6 2021 volatile bool v6found = false; 2022 #endif /* NETINET6 */ 2023 volatile int family = InetMode; 2024 SOCKADDR_LEN_T len; 2025 volatile SOCKADDR_LEN_T socksize = 0; 2026 volatile bool clt_bind; 2027 BITMAP256 d_flags; 2028 char *p; 2029 extern ENVELOPE BlankEnvelope; 2030 2031 /* retranslate {daemon_flags} into bitmap */ 2032 clrbitmap(d_flags); 2033 if ((p = macvalue(macid("{daemon_flags}"), e)) != NULL) 2034 { 2035 for (; *p != '\0'; p++) 2036 { 2037 if (!(isascii(*p) && isspace(*p))) 2038 setbitn(bitidx(*p), d_flags); 2039 } 2040 } 2041 2042 #if NETINET6 2043 v4retry: 2044 #endif /* NETINET6 */ 2045 clt_bind = false; 2046 2047 /* Set up the address for outgoing connection. */ 2048 if (bitnset(D_BINDIF, d_flags) && 2049 (p = macvalue(macid("{if_addr}"), e)) != NULL && 2050 *p != '\0') 2051 { 2052 #if NETINET6 2053 char p6[INET6_ADDRSTRLEN]; 2054 #endif /* NETINET6 */ 2055 2056 memset(&clt_addr, '\0', sizeof clt_addr); 2057 2058 /* infer the address family from the address itself */ 2059 clt_addr.sa.sa_family = addr_family(p); 2060 switch (clt_addr.sa.sa_family) 2061 { 2062 #if NETINET 2063 case AF_INET: 2064 clt_addr.sin.sin_addr.s_addr = inet_addr(p); 2065 if (clt_addr.sin.sin_addr.s_addr != INADDR_NONE && 2066 clt_addr.sin.sin_addr.s_addr != INADDR_LOOPBACK) 2067 { 2068 clt_bind = true; 2069 socksize = sizeof (struct sockaddr_in); 2070 } 2071 break; 2072 #endif /* NETINET */ 2073 2074 #if NETINET6 2075 case AF_INET6: 2076 if (inet_addr(p) != INADDR_NONE) 2077 (void) sm_snprintf(p6, sizeof p6, 2078 "IPv6:::ffff:%s", p); 2079 else 2080 (void) sm_strlcpy(p6, p, sizeof p6); 2081 if (anynet_pton(AF_INET6, p6, 2082 &clt_addr.sin6.sin6_addr) == 1 && 2083 !IN6_IS_ADDR_LOOPBACK(&clt_addr.sin6.sin6_addr)) 2084 { 2085 clt_bind = true; 2086 socksize = sizeof (struct sockaddr_in6); 2087 } 2088 break; 2089 #endif /* NETINET6 */ 2090 2091 #if 0 2092 default: 2093 syserr("554 5.3.5 Address= option unsupported for family %d", 2094 clt_addr.sa.sa_family); 2095 break; 2096 #endif /* 0 */ 2097 } 2098 if (clt_bind) 2099 family = clt_addr.sa.sa_family; 2100 } 2101 2102 /* D_BINDIF not set or not available, fallback to ClientPortOptions */ 2103 if (!clt_bind) 2104 { 2105 STRUCTCOPY(ClientSettings[family].d_addr, clt_addr); 2106 switch (clt_addr.sa.sa_family) 2107 { 2108 #if NETINET 2109 case AF_INET: 2110 if (clt_addr.sin.sin_addr.s_addr == 0) 2111 clt_addr.sin.sin_addr.s_addr = INADDR_ANY; 2112 else 2113 clt_bind = true; 2114 if (clt_addr.sin.sin_port != 0) 2115 clt_bind = true; 2116 socksize = sizeof (struct sockaddr_in); 2117 break; 2118 #endif /* NETINET */ 2119 #if NETINET6 2120 case AF_INET6: 2121 if (IN6_IS_ADDR_UNSPECIFIED(&clt_addr.sin6.sin6_addr)) 2122 clt_addr.sin6.sin6_addr = in6addr_any; 2123 else 2124 clt_bind = true; 2125 socksize = sizeof (struct sockaddr_in6); 2126 if (clt_addr.sin6.sin6_port != 0) 2127 clt_bind = true; 2128 break; 2129 #endif /* NETINET6 */ 2130 #if NETISO 2131 case AF_ISO: 2132 socksize = sizeof clt_addr.siso; 2133 clt_bind = true; 2134 break; 2135 #endif /* NETISO */ 2136 default: 2137 break; 2138 } 2139 } 2140 2141 /* 2142 ** Set up the address for the mailer. 2143 ** Accept "[a.b.c.d]" syntax for host name. 2144 */ 2145 2146 SM_SET_H_ERRNO(0); 2147 errno = 0; 2148 memset(&CurHostAddr, '\0', sizeof CurHostAddr); 2149 memset(&addr, '\0', sizeof addr); 2150 SmtpPhase = mci->mci_phase = "initial connection"; 2151 CurHostName = host; 2152 2153 if (host[0] == '[') 2154 { 2155 p = strchr(host, ']'); 2156 if (p != NULL) 2157 { 2158 #if NETINET 2159 unsigned long hid = INADDR_NONE; 2160 #endif /* NETINET */ 2161 #if NETINET6 2162 struct sockaddr_in6 hid6; 2163 #endif /* NETINET6 */ 2164 2165 *p = '\0'; 2166 #if NETINET6 2167 memset(&hid6, '\0', sizeof hid6); 2168 #endif /* NETINET6 */ 2169 #if NETINET 2170 if (family == AF_INET && 2171 (hid = inet_addr(&host[1])) != INADDR_NONE) 2172 { 2173 addr.sin.sin_family = AF_INET; 2174 addr.sin.sin_addr.s_addr = hid; 2175 } 2176 else 2177 #endif /* NETINET */ 2178 #if NETINET6 2179 if (family == AF_INET6 && 2180 anynet_pton(AF_INET6, &host[1], 2181 &hid6.sin6_addr) == 1) 2182 { 2183 addr.sin6.sin6_family = AF_INET6; 2184 addr.sin6.sin6_addr = hid6.sin6_addr; 2185 } 2186 else 2187 #endif /* NETINET6 */ 2188 { 2189 /* try it as a host name (avoid MX lookup) */ 2190 hp = sm_gethostbyname(&host[1], family); 2191 if (hp == NULL && p[-1] == '.') 2192 { 2193 #if NAMED_BIND 2194 int oldopts = _res.options; 2195 2196 _res.options &= ~(RES_DEFNAMES|RES_DNSRCH); 2197 #endif /* NAMED_BIND */ 2198 p[-1] = '\0'; 2199 hp = sm_gethostbyname(&host[1], 2200 family); 2201 p[-1] = '.'; 2202 #if NAMED_BIND 2203 _res.options = oldopts; 2204 #endif /* NAMED_BIND */ 2205 } 2206 *p = ']'; 2207 goto gothostent; 2208 } 2209 *p = ']'; 2210 } 2211 if (p == NULL) 2212 { 2213 extern char MsgBuf[]; 2214 2215 usrerrenh("5.1.2", 2216 "553 Invalid numeric domain spec \"%s\"", 2217 host); 2218 mci_setstat(mci, EX_NOHOST, "5.1.2", MsgBuf); 2219 errno = EINVAL; 2220 return EX_NOHOST; 2221 } 2222 } 2223 else 2224 { 2225 /* contortion to get around SGI cc complaints */ 2226 { 2227 p = &host[strlen(host) - 1]; 2228 hp = sm_gethostbyname(host, family); 2229 if (hp == NULL && *p == '.') 2230 { 2231 #if NAMED_BIND 2232 int oldopts = _res.options; 2233 2234 _res.options &= ~(RES_DEFNAMES|RES_DNSRCH); 2235 #endif /* NAMED_BIND */ 2236 *p = '\0'; 2237 hp = sm_gethostbyname(host, family); 2238 *p = '.'; 2239 #if NAMED_BIND 2240 _res.options = oldopts; 2241 #endif /* NAMED_BIND */ 2242 } 2243 } 2244 gothostent: 2245 if (hp == NULL) 2246 { 2247 #if NAMED_BIND 2248 /* check for name server timeouts */ 2249 # if NETINET6 2250 if (WorkAroundBrokenAAAA && family == AF_INET6 && 2251 errno == ETIMEDOUT) 2252 { 2253 /* 2254 ** An attempt with family AF_INET may 2255 ** succeed By skipping the next section 2256 ** of code, we will try AF_INET before 2257 ** failing. 2258 */ 2259 2260 if (tTd(16, 10)) 2261 sm_dprintf("makeconnection: WorkAroundBrokenAAAA: Trying AF_INET lookup (AF_INET6 failed)\n"); 2262 } 2263 else 2264 # endif /* NETINET6 */ 2265 { 2266 if (errno == ETIMEDOUT || 2267 h_errno == TRY_AGAIN || 2268 (errno == ECONNREFUSED && UseNameServer)) 2269 { 2270 save_errno = errno; 2271 mci_setstat(mci, EX_TEMPFAIL, 2272 "4.4.3", NULL); 2273 errno = save_errno; 2274 return EX_TEMPFAIL; 2275 } 2276 } 2277 #endif /* NAMED_BIND */ 2278 #if NETINET6 2279 /* 2280 ** Try v6 first, then fall back to v4. 2281 ** If we found a v6 address, but no v4 2282 ** addresses, then TEMPFAIL. 2283 */ 2284 2285 if (family == AF_INET6) 2286 { 2287 family = AF_INET; 2288 goto v4retry; 2289 } 2290 if (v6found) 2291 goto v6tempfail; 2292 #endif /* NETINET6 */ 2293 save_errno = errno; 2294 mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); 2295 errno = save_errno; 2296 return EX_NOHOST; 2297 } 2298 addr.sa.sa_family = hp->h_addrtype; 2299 switch (hp->h_addrtype) 2300 { 2301 #if NETINET 2302 case AF_INET: 2303 memmove(&addr.sin.sin_addr, 2304 hp->h_addr, 2305 INADDRSZ); 2306 break; 2307 #endif /* NETINET */ 2308 2309 #if NETINET6 2310 case AF_INET6: 2311 memmove(&addr.sin6.sin6_addr, 2312 hp->h_addr, 2313 IN6ADDRSZ); 2314 break; 2315 #endif /* NETINET6 */ 2316 2317 default: 2318 if (hp->h_length > sizeof addr.sa.sa_data) 2319 { 2320 syserr("makeconnection: long sa_data: family %d len %d", 2321 hp->h_addrtype, hp->h_length); 2322 mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); 2323 errno = EINVAL; 2324 return EX_NOHOST; 2325 } 2326 memmove(addr.sa.sa_data, hp->h_addr, hp->h_length); 2327 break; 2328 } 2329 addrno = 1; 2330 } 2331 2332 /* 2333 ** Determine the port number. 2334 */ 2335 2336 if (port == 0) 2337 { 2338 #ifdef NO_GETSERVBYNAME 2339 port = htons(25); 2340 #else /* NO_GETSERVBYNAME */ 2341 register struct servent *sp = getservbyname("smtp", "tcp"); 2342 2343 if (sp == NULL) 2344 { 2345 if (LogLevel > 2) 2346 sm_syslog(LOG_ERR, NOQID, 2347 "makeconnection: service \"smtp\" unknown"); 2348 port = htons(25); 2349 } 2350 else 2351 port = sp->s_port; 2352 #endif /* NO_GETSERVBYNAME */ 2353 } 2354 2355 #if NETINET6 2356 if (addr.sa.sa_family == AF_INET6 && 2357 IN6_IS_ADDR_V4MAPPED(&addr.sin6.sin6_addr) && 2358 ClientSettings[AF_INET].d_addr.sa.sa_family != 0) 2359 { 2360 /* 2361 ** Ignore mapped IPv4 address since 2362 ** there is a ClientPortOptions setting 2363 ** for IPv4. 2364 */ 2365 2366 goto nextaddr; 2367 } 2368 #endif /* NETINET6 */ 2369 2370 switch (addr.sa.sa_family) 2371 { 2372 #if NETINET 2373 case AF_INET: 2374 addr.sin.sin_port = port; 2375 addrlen = sizeof (struct sockaddr_in); 2376 break; 2377 #endif /* NETINET */ 2378 2379 #if NETINET6 2380 case AF_INET6: 2381 addr.sin6.sin6_port = port; 2382 addrlen = sizeof (struct sockaddr_in6); 2383 break; 2384 #endif /* NETINET6 */ 2385 2386 #if NETISO 2387 case AF_ISO: 2388 /* assume two byte transport selector */ 2389 memmove(TSEL((struct sockaddr_iso *) &addr), (char *) &port, 2); 2390 addrlen = sizeof (struct sockaddr_iso); 2391 break; 2392 #endif /* NETISO */ 2393 2394 default: 2395 syserr("Can't connect to address family %d", addr.sa.sa_family); 2396 mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); 2397 errno = EINVAL; 2398 #if NETINET6 2399 if (hp != NULL) 2400 freehostent(hp); 2401 #endif /* NETINET6 */ 2402 return EX_NOHOST; 2403 } 2404 2405 /* 2406 ** Try to actually open the connection. 2407 */ 2408 2409 #if XLA 2410 /* if too many connections, don't bother trying */ 2411 if (!xla_noqueue_ok(host)) 2412 { 2413 # if NETINET6 2414 if (hp != NULL) 2415 freehostent(hp); 2416 # endif /* NETINET6 */ 2417 return EX_TEMPFAIL; 2418 } 2419 #endif /* XLA */ 2420 2421 firstconnect = true; 2422 for (;;) 2423 { 2424 if (tTd(16, 1)) 2425 sm_dprintf("makeconnection (%s [%s].%d (%d))\n", 2426 host, anynet_ntoa(&addr), ntohs(port), 2427 (int) addr.sa.sa_family); 2428 2429 /* save for logging */ 2430 CurHostAddr = addr; 2431 2432 #if HASRRESVPORT 2433 if (bitnset(M_SECURE_PORT, mci->mci_mailer->m_flags)) 2434 { 2435 int rport = IPPORT_RESERVED - 1; 2436 2437 s = rresvport(&rport); 2438 } 2439 else 2440 #endif /* HASRRESVPORT */ 2441 { 2442 s = socket(addr.sa.sa_family, SOCK_STREAM, 0); 2443 } 2444 if (s < 0) 2445 { 2446 save_errno = errno; 2447 syserr("makeconnection: cannot create socket"); 2448 #if XLA 2449 xla_host_end(host); 2450 #endif /* XLA */ 2451 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2452 #if NETINET6 2453 if (hp != NULL) 2454 freehostent(hp); 2455 #endif /* NETINET6 */ 2456 errno = save_errno; 2457 return EX_TEMPFAIL; 2458 } 2459 2460 #ifdef SO_SNDBUF 2461 if (ClientSettings[family].d_tcpsndbufsize > 0) 2462 { 2463 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, 2464 (char *) &ClientSettings[family].d_tcpsndbufsize, 2465 sizeof(ClientSettings[family].d_tcpsndbufsize)) < 0) 2466 syserr("makeconnection: setsockopt(SO_SNDBUF)"); 2467 } 2468 #endif /* SO_SNDBUF */ 2469 #ifdef SO_RCVBUF 2470 if (ClientSettings[family].d_tcprcvbufsize > 0) 2471 { 2472 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 2473 (char *) &ClientSettings[family].d_tcprcvbufsize, 2474 sizeof(ClientSettings[family].d_tcprcvbufsize)) < 0) 2475 syserr("makeconnection: setsockopt(SO_RCVBUF)"); 2476 } 2477 #endif /* SO_RCVBUF */ 2478 2479 if (tTd(16, 1)) 2480 sm_dprintf("makeconnection: fd=%d\n", s); 2481 2482 /* turn on network debugging? */ 2483 if (tTd(16, 101)) 2484 { 2485 int on = 1; 2486 2487 (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, 2488 (char *)&on, sizeof on); 2489 } 2490 if (e->e_xfp != NULL) /* for debugging */ 2491 (void) sm_io_flush(e->e_xfp, SM_TIME_DEFAULT); 2492 errno = 0; /* for debugging */ 2493 2494 if (clt_bind) 2495 { 2496 int on = 1; 2497 2498 switch (clt_addr.sa.sa_family) 2499 { 2500 #if NETINET 2501 case AF_INET: 2502 if (clt_addr.sin.sin_port != 0) 2503 (void) setsockopt(s, SOL_SOCKET, 2504 SO_REUSEADDR, 2505 (char *) &on, 2506 sizeof on); 2507 break; 2508 #endif /* NETINET */ 2509 2510 #if NETINET6 2511 case AF_INET6: 2512 if (clt_addr.sin6.sin6_port != 0) 2513 (void) setsockopt(s, SOL_SOCKET, 2514 SO_REUSEADDR, 2515 (char *) &on, 2516 sizeof on); 2517 break; 2518 #endif /* NETINET6 */ 2519 } 2520 2521 if (bind(s, &clt_addr.sa, socksize) < 0) 2522 { 2523 save_errno = errno; 2524 (void) close(s); 2525 errno = save_errno; 2526 syserr("makeconnection: cannot bind socket [%s]", 2527 anynet_ntoa(&clt_addr)); 2528 #if NETINET6 2529 if (hp != NULL) 2530 freehostent(hp); 2531 #endif /* NETINET6 */ 2532 errno = save_errno; 2533 return EX_TEMPFAIL; 2534 } 2535 } 2536 2537 /* 2538 ** Linux seems to hang in connect for 90 minutes (!!!). 2539 ** Time out the connect to avoid this problem. 2540 */ 2541 2542 if (setjmp(CtxConnectTimeout) == 0) 2543 { 2544 int i; 2545 2546 if (e->e_ntries <= 0 && TimeOuts.to_iconnect != 0) 2547 ev = sm_setevent(TimeOuts.to_iconnect, 2548 connecttimeout, 0); 2549 else if (TimeOuts.to_connect != 0) 2550 ev = sm_setevent(TimeOuts.to_connect, 2551 connecttimeout, 0); 2552 else 2553 ev = NULL; 2554 2555 switch (ConnectOnlyTo.sa.sa_family) 2556 { 2557 #if NETINET 2558 case AF_INET: 2559 addr.sin.sin_addr.s_addr = ConnectOnlyTo.sin.sin_addr.s_addr; 2560 break; 2561 #endif /* NETINET */ 2562 2563 #if NETINET6 2564 case AF_INET6: 2565 memmove(&addr.sin6.sin6_addr, 2566 &ConnectOnlyTo.sin6.sin6_addr, 2567 IN6ADDRSZ); 2568 break; 2569 #endif /* NETINET6 */ 2570 } 2571 i = connect(s, (struct sockaddr *) &addr, addrlen); 2572 save_errno = errno; 2573 if (ev != NULL) 2574 sm_clrevent(ev); 2575 if (i >= 0) 2576 break; 2577 } 2578 else 2579 save_errno = errno; 2580 2581 /* couldn't connect.... figure out why */ 2582 (void) close(s); 2583 2584 /* if running demand-dialed connection, try again */ 2585 if (DialDelay > 0 && firstconnect && 2586 bitnset(M_DIALDELAY, mci->mci_mailer->m_flags)) 2587 { 2588 if (tTd(16, 1)) 2589 sm_dprintf("Connect failed (%s); trying again...\n", 2590 sm_errstring(save_errno)); 2591 firstconnect = false; 2592 (void) sleep(DialDelay); 2593 continue; 2594 } 2595 2596 if (LogLevel > 13) 2597 sm_syslog(LOG_INFO, e->e_id, 2598 "makeconnection (%s [%s]) failed: %s", 2599 host, anynet_ntoa(&addr), 2600 sm_errstring(save_errno)); 2601 2602 #if NETINET6 2603 nextaddr: 2604 #endif /* NETINET6 */ 2605 if (hp != NULL && hp->h_addr_list[addrno] != NULL && 2606 (enough == 0 || curtime() < enough)) 2607 { 2608 if (tTd(16, 1)) 2609 sm_dprintf("Connect failed (%s); trying new address....\n", 2610 sm_errstring(save_errno)); 2611 switch (addr.sa.sa_family) 2612 { 2613 #if NETINET 2614 case AF_INET: 2615 memmove(&addr.sin.sin_addr, 2616 hp->h_addr_list[addrno++], 2617 INADDRSZ); 2618 break; 2619 #endif /* NETINET */ 2620 2621 #if NETINET6 2622 case AF_INET6: 2623 memmove(&addr.sin6.sin6_addr, 2624 hp->h_addr_list[addrno++], 2625 IN6ADDRSZ); 2626 break; 2627 #endif /* NETINET6 */ 2628 2629 default: 2630 memmove(addr.sa.sa_data, 2631 hp->h_addr_list[addrno++], 2632 hp->h_length); 2633 break; 2634 } 2635 continue; 2636 } 2637 errno = save_errno; 2638 2639 #if NETINET6 2640 if (family == AF_INET6) 2641 { 2642 if (tTd(16, 1)) 2643 sm_dprintf("Connect failed (%s); retrying with AF_INET....\n", 2644 sm_errstring(save_errno)); 2645 v6found = true; 2646 family = AF_INET; 2647 if (hp != NULL) 2648 { 2649 freehostent(hp); 2650 hp = NULL; 2651 } 2652 goto v4retry; 2653 } 2654 v6tempfail: 2655 #endif /* NETINET6 */ 2656 /* couldn't open connection */ 2657 #if NETINET6 2658 /* Don't clobber an already saved errno from v4retry */ 2659 if (errno > 0) 2660 #endif /* NETINET6 */ 2661 save_errno = errno; 2662 if (tTd(16, 1)) 2663 sm_dprintf("Connect failed (%s)\n", 2664 sm_errstring(save_errno)); 2665 #if XLA 2666 xla_host_end(host); 2667 #endif /* XLA */ 2668 mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); 2669 #if NETINET6 2670 if (hp != NULL) 2671 freehostent(hp); 2672 #endif /* NETINET6 */ 2673 errno = save_errno; 2674 return EX_TEMPFAIL; 2675 } 2676 2677 #if NETINET6 2678 if (hp != NULL) 2679 { 2680 freehostent(hp); 2681 hp = NULL; 2682 } 2683 #endif /* NETINET6 */ 2684 2685 /* connection ok, put it into canonical form */ 2686 mci->mci_out = NULL; 2687 if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 2688 (void *) &s, 2689 SM_IO_WRONLY, NULL)) == NULL || 2690 (s = dup(s)) < 0 || 2691 (mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 2692 (void *) &s, 2693 SM_IO_RDONLY, NULL)) == NULL) 2694 { 2695 save_errno = errno; 2696 syserr("cannot open SMTP client channel, fd=%d", s); 2697 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2698 if (mci->mci_out != NULL) 2699 (void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT); 2700 (void) close(s); 2701 errno = save_errno; 2702 return EX_TEMPFAIL; 2703 } 2704 sm_io_automode(mci->mci_out, mci->mci_in); 2705 2706 /* set {client_flags} */ 2707 if (ClientSettings[addr.sa.sa_family].d_mflags != NULL) 2708 { 2709 macdefine(&mci->mci_macro, A_PERM, 2710 macid("{client_flags}"), 2711 ClientSettings[addr.sa.sa_family].d_mflags); 2712 } 2713 else 2714 macdefine(&mci->mci_macro, A_PERM, 2715 macid("{client_flags}"), ""); 2716 2717 /* "add" {client_flags} to bitmap */ 2718 if (bitnset(D_IFNHELO, ClientSettings[addr.sa.sa_family].d_flags)) 2719 { 2720 /* look for just this one flag */ 2721 setbitn(D_IFNHELO, d_flags); 2722 } 2723 2724 /* find out name for Interface through which we connect */ 2725 len = sizeof addr; 2726 if (getsockname(s, &addr.sa, &len) == 0) 2727 { 2728 char *name; 2729 char family[5]; 2730 2731 macdefine(&BlankEnvelope.e_macro, A_TEMP, 2732 macid("{if_addr_out}"), anynet_ntoa(&addr)); 2733 (void) sm_snprintf(family, sizeof(family), "%d", 2734 addr.sa.sa_family); 2735 macdefine(&BlankEnvelope.e_macro, A_TEMP, 2736 macid("{if_family_out}"), family); 2737 2738 name = hostnamebyanyaddr(&addr); 2739 macdefine(&BlankEnvelope.e_macro, A_TEMP, 2740 macid("{if_name_out}"), name); 2741 if (LogLevel > 11) 2742 { 2743 /* log connection information */ 2744 sm_syslog(LOG_INFO, e->e_id, 2745 "SMTP outgoing connect on %.40s", name); 2746 } 2747 if (bitnset(D_IFNHELO, d_flags)) 2748 { 2749 if (name[0] != '[' && strchr(name, '.') != NULL) 2750 mci->mci_heloname = newstr(name); 2751 } 2752 } 2753 else 2754 { 2755 macdefine(&BlankEnvelope.e_macro, A_PERM, 2756 macid("{if_name_out}"), NULL); 2757 macdefine(&BlankEnvelope.e_macro, A_PERM, 2758 macid("{if_addr_out}"), NULL); 2759 macdefine(&BlankEnvelope.e_macro, A_PERM, 2760 macid("{if_family_out}"), NULL); 2761 } 2762 mci_setstat(mci, EX_OK, NULL, NULL); 2763 return EX_OK; 2764 } 2765 2766 static void 2767 connecttimeout() 2768 { 2769 /* 2770 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 2771 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 2772 ** DOING. 2773 */ 2774 2775 errno = ETIMEDOUT; 2776 longjmp(CtxConnectTimeout, 1); 2777 } 2778 /* 2779 ** MAKECONNECTION_DS -- make a connection to a domain socket. 2780 ** 2781 ** Parameters: 2782 ** mux_path -- the path of the socket to connect to. 2783 ** mci -- a pointer to the mail connection information 2784 ** structure to be filled in. 2785 ** 2786 ** Returns: 2787 ** An exit code telling whether the connection could be 2788 ** made and if not why not. 2789 ** 2790 ** Side Effects: 2791 ** none. 2792 */ 2793 2794 #if NETUNIX 2795 int 2796 makeconnection_ds(mux_path, mci) 2797 char *mux_path; 2798 register MCI *mci; 2799 { 2800 int sock; 2801 int rval, save_errno; 2802 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_ROOTOK|SFF_EXECOK; 2803 struct sockaddr_un unix_addr; 2804 2805 /* if not safe, don't connect */ 2806 rval = safefile(mux_path, RunAsUid, RunAsGid, RunAsUserName, 2807 sff, S_IRUSR|S_IWUSR, NULL); 2808 2809 if (rval != 0) 2810 { 2811 syserr("makeconnection_ds: unsafe domain socket"); 2812 mci_setstat(mci, EX_TEMPFAIL, "4.3.5", NULL); 2813 errno = rval; 2814 return EX_TEMPFAIL; 2815 } 2816 2817 /* prepare address structure */ 2818 memset(&unix_addr, '\0', sizeof unix_addr); 2819 unix_addr.sun_family = AF_UNIX; 2820 2821 if (strlen(mux_path) >= sizeof unix_addr.sun_path) 2822 { 2823 syserr("makeconnection_ds: domain socket name too long"); 2824 2825 /* XXX why TEMPFAIL but 5.x.y ? */ 2826 mci_setstat(mci, EX_TEMPFAIL, "5.3.5", NULL); 2827 errno = ENAMETOOLONG; 2828 return EX_UNAVAILABLE; 2829 } 2830 (void) sm_strlcpy(unix_addr.sun_path, mux_path, 2831 sizeof unix_addr.sun_path); 2832 2833 /* initialize domain socket */ 2834 sock = socket(AF_UNIX, SOCK_STREAM, 0); 2835 if (sock == -1) 2836 { 2837 save_errno = errno; 2838 syserr("makeconnection_ds: could not create domain socket"); 2839 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2840 errno = save_errno; 2841 return EX_TEMPFAIL; 2842 } 2843 2844 /* connect to server */ 2845 if (connect(sock, (struct sockaddr *) &unix_addr, 2846 sizeof(unix_addr)) == -1) 2847 { 2848 save_errno = errno; 2849 syserr("Could not connect to socket %s", mux_path); 2850 mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); 2851 (void) close(sock); 2852 errno = save_errno; 2853 return EX_TEMPFAIL; 2854 } 2855 2856 /* connection ok, put it into canonical form */ 2857 mci->mci_out = NULL; 2858 if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 2859 (void *) &sock, SM_IO_WRONLY, NULL)) 2860 == NULL 2861 || (sock = dup(sock)) < 0 || 2862 (mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 2863 (void *) &sock, SM_IO_RDONLY, NULL)) 2864 == NULL) 2865 { 2866 save_errno = errno; 2867 syserr("cannot open SMTP client channel, fd=%d", sock); 2868 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2869 if (mci->mci_out != NULL) 2870 (void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT); 2871 (void) close(sock); 2872 errno = save_errno; 2873 return EX_TEMPFAIL; 2874 } 2875 sm_io_automode(mci->mci_out, mci->mci_in); 2876 2877 mci_setstat(mci, EX_OK, NULL, NULL); 2878 errno = 0; 2879 return EX_OK; 2880 } 2881 #endif /* NETUNIX */ 2882 /* 2883 ** SHUTDOWN_DAEMON -- Performs a clean shutdown of the daemon 2884 ** 2885 ** Parameters: 2886 ** none. 2887 ** 2888 ** Returns: 2889 ** none. 2890 ** 2891 ** Side Effects: 2892 ** closes control socket, exits. 2893 */ 2894 2895 void 2896 shutdown_daemon() 2897 { 2898 int i; 2899 char *reason; 2900 2901 sm_allsignals(true); 2902 2903 reason = ShutdownRequest; 2904 ShutdownRequest = NULL; 2905 PendingSignal = 0; 2906 2907 if (LogLevel > 79) 2908 sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt (%s)", 2909 reason == NULL ? "implicit call" : reason); 2910 2911 FileName = NULL; 2912 closecontrolsocket(true); 2913 #if XLA 2914 xla_all_end(); 2915 #endif /* XLA */ 2916 2917 for (i = 0; i < NDaemons; i++) 2918 { 2919 if (Daemons[i].d_socket >= 0) 2920 { 2921 (void) close(Daemons[i].d_socket); 2922 Daemons[i].d_socket = -1; 2923 2924 #if _FFR_DAEMON_NETUNIX 2925 # if NETUNIX 2926 /* Remove named sockets */ 2927 if (Daemons[i].d_addr.sa.sa_family == AF_UNIX) 2928 { 2929 int rval; 2930 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_MUSTOWN|SFF_EXECOK|SFF_CREAT; 2931 2932 /* if not safe, don't use it */ 2933 rval = safefile(Daemons[i].d_addr.sunix.sun_path, 2934 RunAsUid, RunAsGid, 2935 RunAsUserName, sff, 2936 S_IRUSR|S_IWUSR, NULL); 2937 if (rval == 0 && 2938 unlink(Daemons[i].d_addr.sunix.sun_path) < 0) 2939 { 2940 sm_syslog(LOG_WARNING, NOQID, 2941 "Could not remove daemon %s socket: %s: %s", 2942 Daemons[i].d_name, 2943 Daemons[i].d_addr.sunix.sun_path, 2944 sm_errstring(errno)); 2945 } 2946 } 2947 # endif /* NETUNIX */ 2948 #endif /* _FFR_DAEMON_NETUNIX */ 2949 } 2950 } 2951 2952 finis(false, true, EX_OK); 2953 } 2954 /* 2955 ** RESTART_DAEMON -- Performs a clean restart of the daemon 2956 ** 2957 ** Parameters: 2958 ** none. 2959 ** 2960 ** Returns: 2961 ** none. 2962 ** 2963 ** Side Effects: 2964 ** restarts the daemon or exits if restart fails. 2965 */ 2966 2967 /* Make a non-DFL/IGN signal a noop */ 2968 #define SM_NOOP_SIGNAL(sig, old) \ 2969 do \ 2970 { \ 2971 (old) = sm_signal((sig), sm_signal_noop); \ 2972 if ((old) == SIG_IGN || (old) == SIG_DFL) \ 2973 (void) sm_signal((sig), (old)); \ 2974 } while (0) 2975 2976 void 2977 restart_daemon() 2978 { 2979 bool drop; 2980 int i; 2981 int save_errno; 2982 char *reason; 2983 sigfunc_t ignore, oalrm, ousr1; 2984 extern int DtableSize; 2985 2986 /* clear the events to turn off SIGALRMs */ 2987 sm_clear_events(); 2988 sm_allsignals(true); 2989 2990 reason = RestartRequest; 2991 RestartRequest = NULL; 2992 PendingSignal = 0; 2993 2994 if (SaveArgv[0][0] != '/') 2995 { 2996 if (LogLevel > 3) 2997 sm_syslog(LOG_INFO, NOQID, 2998 "could not restart: need full path"); 2999 finis(false, true, EX_OSFILE); 3000 /* NOTREACHED */ 3001 } 3002 if (LogLevel > 3) 3003 sm_syslog(LOG_INFO, NOQID, "restarting %s due to %s", 3004 SaveArgv[0], 3005 reason == NULL ? "implicit call" : reason); 3006 3007 closecontrolsocket(true); 3008 #if SM_CONF_SHM 3009 cleanup_shm(DaemonPid == getpid()); 3010 #endif /* SM_CONF_SHM */ 3011 3012 /* 3013 ** Want to drop to the user who started the process in all cases 3014 ** *but* when running as "smmsp" for the clientmqueue queue run 3015 ** daemon. In that case, UseMSP will be true, RunAsUid should not 3016 ** be root, and RealUid should be either 0 or RunAsUid. 3017 */ 3018 3019 drop = !(UseMSP && RunAsUid != 0 && 3020 (RealUid == 0 || RealUid == RunAsUid)); 3021 3022 if (drop_privileges(drop) != EX_OK) 3023 { 3024 if (LogLevel > 0) 3025 sm_syslog(LOG_ALERT, NOQID, 3026 "could not drop privileges: %s", 3027 sm_errstring(errno)); 3028 finis(false, true, EX_OSERR); 3029 /* NOTREACHED */ 3030 } 3031 3032 /* arrange for all the files to be closed */ 3033 for (i = 3; i < DtableSize; i++) 3034 { 3035 register int j; 3036 3037 if ((j = fcntl(i, F_GETFD, 0)) != -1) 3038 (void) fcntl(i, F_SETFD, j | FD_CLOEXEC); 3039 } 3040 3041 /* 3042 ** Need to allow signals before execve() to make them "harmless". 3043 ** However, the default action can be "terminate", so it isn't 3044 ** really harmless. Setting signals to IGN will cause them to be 3045 ** ignored in the new process to, so that isn't a good alternative. 3046 */ 3047 3048 SM_NOOP_SIGNAL(SIGALRM, oalrm); 3049 SM_NOOP_SIGNAL(SIGCHLD, ignore); 3050 SM_NOOP_SIGNAL(SIGHUP, ignore); 3051 SM_NOOP_SIGNAL(SIGINT, ignore); 3052 SM_NOOP_SIGNAL(SIGPIPE, ignore); 3053 SM_NOOP_SIGNAL(SIGTERM, ignore); 3054 #ifdef SIGUSR1 3055 SM_NOOP_SIGNAL(SIGUSR1, ousr1); 3056 #endif /* SIGUSR1 */ 3057 3058 /* Turn back on signals */ 3059 sm_allsignals(false); 3060 3061 (void) execve(SaveArgv[0], (ARGV_T) SaveArgv, (ARGV_T) ExternalEnviron); 3062 save_errno = errno; 3063 3064 /* block signals again and restore needed signals */ 3065 sm_allsignals(true); 3066 3067 /* For finis() events */ 3068 (void) sm_signal(SIGALRM, oalrm); 3069 3070 #ifdef SIGUSR1 3071 /* For debugging finis() */ 3072 (void) sm_signal(SIGUSR1, ousr1); 3073 #endif /* SIGUSR1 */ 3074 3075 errno = save_errno; 3076 if (LogLevel > 0) 3077 sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %s", 3078 SaveArgv[0], sm_errstring(errno)); 3079 finis(false, true, EX_OSFILE); 3080 /* NOTREACHED */ 3081 } 3082 /* 3083 ** MYHOSTNAME -- return the name of this host. 3084 ** 3085 ** Parameters: 3086 ** hostbuf -- a place to return the name of this host. 3087 ** size -- the size of hostbuf. 3088 ** 3089 ** Returns: 3090 ** A list of aliases for this host. 3091 ** 3092 ** Side Effects: 3093 ** Adds numeric codes to $=w. 3094 */ 3095 3096 struct hostent * 3097 myhostname(hostbuf, size) 3098 char hostbuf[]; 3099 int size; 3100 { 3101 register struct hostent *hp; 3102 3103 if (gethostname(hostbuf, size) < 0 || hostbuf[0] == '\0') 3104 (void) sm_strlcpy(hostbuf, "localhost", size); 3105 hp = sm_gethostbyname(hostbuf, InetMode); 3106 #if NETINET && NETINET6 3107 if (hp == NULL && InetMode == AF_INET6) 3108 { 3109 /* 3110 ** It's possible that this IPv6 enabled machine doesn't 3111 ** actually have any IPv6 interfaces and, therefore, no 3112 ** IPv6 addresses. Fall back to AF_INET. 3113 */ 3114 3115 hp = sm_gethostbyname(hostbuf, AF_INET); 3116 } 3117 #endif /* NETINET && NETINET6 */ 3118 if (hp == NULL) 3119 return NULL; 3120 if (strchr(hp->h_name, '.') != NULL || strchr(hostbuf, '.') == NULL) 3121 (void) cleanstrcpy(hostbuf, hp->h_name, size); 3122 3123 #if NETINFO 3124 if (strchr(hostbuf, '.') == NULL) 3125 { 3126 char *domainname; 3127 3128 domainname = ni_propval("/locations", NULL, "resolver", 3129 "domain", '\0'); 3130 if (domainname != NULL && 3131 strlen(domainname) + strlen(hostbuf) + 1 < size) 3132 (void) sm_strlcat2(hostbuf, ".", domainname, size); 3133 } 3134 #endif /* NETINFO */ 3135 3136 /* 3137 ** If there is still no dot in the name, try looking for a 3138 ** dotted alias. 3139 */ 3140 3141 if (strchr(hostbuf, '.') == NULL) 3142 { 3143 char **ha; 3144 3145 for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++) 3146 { 3147 if (strchr(*ha, '.') != NULL) 3148 { 3149 (void) cleanstrcpy(hostbuf, *ha, size - 1); 3150 hostbuf[size - 1] = '\0'; 3151 break; 3152 } 3153 } 3154 } 3155 3156 /* 3157 ** If _still_ no dot, wait for a while and try again -- it is 3158 ** possible that some service is starting up. This can result 3159 ** in excessive delays if the system is badly configured, but 3160 ** there really isn't a way around that, particularly given that 3161 ** the config file hasn't been read at this point. 3162 ** All in all, a bit of a mess. 3163 */ 3164 3165 if (strchr(hostbuf, '.') == NULL && 3166 !getcanonname(hostbuf, size, true, NULL)) 3167 { 3168 sm_syslog(LOG_CRIT, NOQID, 3169 "My unqualified host name (%s) unknown; sleeping for retry", 3170 hostbuf); 3171 message("My unqualified host name (%s) unknown; sleeping for retry", 3172 hostbuf); 3173 (void) sleep(60); 3174 if (!getcanonname(hostbuf, size, true, NULL)) 3175 { 3176 sm_syslog(LOG_ALERT, NOQID, 3177 "unable to qualify my own domain name (%s) -- using short name", 3178 hostbuf); 3179 message("WARNING: unable to qualify my own domain name (%s) -- using short name", 3180 hostbuf); 3181 } 3182 } 3183 return hp; 3184 } 3185 /* 3186 ** ADDRCMP -- compare two host addresses 3187 ** 3188 ** Parameters: 3189 ** hp -- hostent structure for the first address 3190 ** ha -- actual first address 3191 ** sa -- second address 3192 ** 3193 ** Returns: 3194 ** 0 -- if ha and sa match 3195 ** else -- they don't match 3196 */ 3197 3198 static int 3199 addrcmp(hp, ha, sa) 3200 struct hostent *hp; 3201 char *ha; 3202 SOCKADDR *sa; 3203 { 3204 #if NETINET6 3205 unsigned char *a; 3206 #endif /* NETINET6 */ 3207 3208 switch (sa->sa.sa_family) 3209 { 3210 #if NETINET 3211 case AF_INET: 3212 if (hp->h_addrtype == AF_INET) 3213 return memcmp(ha, (char *) &sa->sin.sin_addr, INADDRSZ); 3214 break; 3215 #endif /* NETINET */ 3216 3217 #if NETINET6 3218 case AF_INET6: 3219 a = (unsigned char *) &sa->sin6.sin6_addr; 3220 3221 /* Straight binary comparison */ 3222 if (hp->h_addrtype == AF_INET6) 3223 return memcmp(ha, a, IN6ADDRSZ); 3224 3225 /* If IPv4-mapped IPv6 address, compare the IPv4 section */ 3226 if (hp->h_addrtype == AF_INET && 3227 IN6_IS_ADDR_V4MAPPED(&sa->sin6.sin6_addr)) 3228 return memcmp(a + IN6ADDRSZ - INADDRSZ, ha, INADDRSZ); 3229 break; 3230 #endif /* NETINET6 */ 3231 } 3232 return -1; 3233 } 3234 /* 3235 ** GETAUTHINFO -- get the real host name associated with a file descriptor 3236 ** 3237 ** Uses RFC1413 protocol to try to get info from the other end. 3238 ** 3239 ** Parameters: 3240 ** fd -- the descriptor 3241 ** may_be_forged -- an outage that is set to true if the 3242 ** forward lookup of RealHostName does not match 3243 ** RealHostAddr; set to false if they do match. 3244 ** 3245 ** Returns: 3246 ** The user@host information associated with this descriptor. 3247 */ 3248 3249 static jmp_buf CtxAuthTimeout; 3250 3251 static void 3252 authtimeout() 3253 { 3254 /* 3255 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 3256 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 3257 ** DOING. 3258 */ 3259 3260 errno = ETIMEDOUT; 3261 longjmp(CtxAuthTimeout, 1); 3262 } 3263 3264 char * 3265 getauthinfo(fd, may_be_forged) 3266 int fd; 3267 bool *may_be_forged; 3268 { 3269 unsigned short SM_NONVOLATILE port = 0; 3270 SOCKADDR_LEN_T falen; 3271 register char *volatile p = NULL; 3272 SOCKADDR la; 3273 SOCKADDR_LEN_T lalen; 3274 #ifndef NO_GETSERVBYNAME 3275 register struct servent *sp; 3276 # if NETINET 3277 static unsigned short port4 = 0; 3278 # endif /* NETINET */ 3279 # if NETINET6 3280 static unsigned short port6 = 0; 3281 # endif /* NETINET6 */ 3282 #endif /* ! NO_GETSERVBYNAME */ 3283 volatile int s; 3284 int i = 0; 3285 size_t len; 3286 SM_EVENT *ev; 3287 int nleft; 3288 struct hostent *hp; 3289 char *ostype = NULL; 3290 char **ha; 3291 char ibuf[MAXNAME + 1]; 3292 static char hbuf[MAXNAME * 2 + 11]; 3293 3294 *may_be_forged = false; 3295 falen = sizeof RealHostAddr; 3296 if (isatty(fd) || (i = getpeername(fd, &RealHostAddr.sa, &falen)) < 0 || 3297 falen <= 0 || RealHostAddr.sa.sa_family == 0) 3298 { 3299 if (i < 0) 3300 { 3301 /* 3302 ** ENOTSOCK is OK: bail on anything else, but reset 3303 ** errno in this case, so a mis-report doesn't 3304 ** happen later. 3305 */ 3306 3307 if (errno != ENOTSOCK) 3308 return NULL; 3309 errno = 0; 3310 } 3311 (void) sm_strlcpyn(hbuf, sizeof hbuf, 2, RealUserName, 3312 "@localhost"); 3313 if (tTd(9, 1)) 3314 sm_dprintf("getauthinfo: %s\n", hbuf); 3315 return hbuf; 3316 } 3317 3318 if (RealHostName == NULL) 3319 { 3320 /* translate that to a host name */ 3321 RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr)); 3322 if (strlen(RealHostName) > MAXNAME) 3323 RealHostName[MAXNAME] = '\0'; /* XXX - 1 ? */ 3324 } 3325 3326 /* cross check RealHostName with forward DNS lookup */ 3327 if (anynet_ntoa(&RealHostAddr)[0] != '[' && 3328 RealHostName[0] != '[') 3329 { 3330 int family; 3331 3332 family = RealHostAddr.sa.sa_family; 3333 #if NETINET6 && NEEDSGETIPNODE 3334 /* 3335 ** If RealHostAddr is an IPv6 connection with an 3336 ** IPv4-mapped address, we need RealHostName's IPv4 3337 ** address(es) for addrcmp() to compare against 3338 ** RealHostAddr. 3339 ** 3340 ** Actually, we only need to do this for systems 3341 ** which NEEDSGETIPNODE since the real getipnodebyname() 3342 ** already does V4MAPPED address via the AI_V4MAPPEDCFG 3343 ** flag. A better fix to this problem is to add this 3344 ** functionality to our stub getipnodebyname(). 3345 */ 3346 3347 if (family == AF_INET6 && 3348 IN6_IS_ADDR_V4MAPPED(&RealHostAddr.sin6.sin6_addr)) 3349 family = AF_INET; 3350 #endif /* NETINET6 && NEEDSGETIPNODE */ 3351 3352 /* try to match the reverse against the forward lookup */ 3353 hp = sm_gethostbyname(RealHostName, family); 3354 if (hp == NULL) 3355 *may_be_forged = true; 3356 else 3357 { 3358 for (ha = hp->h_addr_list; *ha != NULL; ha++) 3359 { 3360 if (addrcmp(hp, *ha, &RealHostAddr) == 0) 3361 break; 3362 } 3363 *may_be_forged = *ha == NULL; 3364 #if NETINET6 3365 freehostent(hp); 3366 hp = NULL; 3367 #endif /* NETINET6 */ 3368 } 3369 } 3370 3371 if (TimeOuts.to_ident == 0) 3372 goto noident; 3373 3374 lalen = sizeof la; 3375 switch (RealHostAddr.sa.sa_family) 3376 { 3377 #if NETINET 3378 case AF_INET: 3379 if (getsockname(fd, &la.sa, &lalen) < 0 || 3380 lalen <= 0 || 3381 la.sa.sa_family != AF_INET) 3382 { 3383 /* no ident info */ 3384 goto noident; 3385 } 3386 port = RealHostAddr.sin.sin_port; 3387 3388 /* create ident query */ 3389 (void) sm_snprintf(ibuf, sizeof ibuf, "%d,%d\r\n", 3390 ntohs(RealHostAddr.sin.sin_port), 3391 ntohs(la.sin.sin_port)); 3392 3393 /* create local address */ 3394 la.sin.sin_port = 0; 3395 3396 /* create foreign address */ 3397 # ifdef NO_GETSERVBYNAME 3398 RealHostAddr.sin.sin_port = htons(113); 3399 # else /* NO_GETSERVBYNAME */ 3400 3401 /* 3402 ** getservbyname() consumes about 5% of the time 3403 ** when receiving a small message (almost all of the time 3404 ** spent in this routine). 3405 ** Hence we store the port in a static variable 3406 ** to save this time. 3407 ** The portnumber shouldn't change very often... 3408 ** This code makes the assumption that the port number 3409 ** is not 0. 3410 */ 3411 3412 if (port4 == 0) 3413 { 3414 sp = getservbyname("auth", "tcp"); 3415 if (sp != NULL) 3416 port4 = sp->s_port; 3417 else 3418 port4 = htons(113); 3419 } 3420 RealHostAddr.sin.sin_port = port4; 3421 break; 3422 # endif /* NO_GETSERVBYNAME */ 3423 #endif /* NETINET */ 3424 3425 #if NETINET6 3426 case AF_INET6: 3427 if (getsockname(fd, &la.sa, &lalen) < 0 || 3428 lalen <= 0 || 3429 la.sa.sa_family != AF_INET6) 3430 { 3431 /* no ident info */ 3432 goto noident; 3433 } 3434 port = RealHostAddr.sin6.sin6_port; 3435 3436 /* create ident query */ 3437 (void) sm_snprintf(ibuf, sizeof ibuf, "%d,%d\r\n", 3438 ntohs(RealHostAddr.sin6.sin6_port), 3439 ntohs(la.sin6.sin6_port)); 3440 3441 /* create local address */ 3442 la.sin6.sin6_port = 0; 3443 3444 /* create foreign address */ 3445 # ifdef NO_GETSERVBYNAME 3446 RealHostAddr.sin6.sin6_port = htons(113); 3447 # else /* NO_GETSERVBYNAME */ 3448 if (port6 == 0) 3449 { 3450 sp = getservbyname("auth", "tcp"); 3451 if (sp != NULL) 3452 port6 = sp->s_port; 3453 else 3454 port6 = htons(113); 3455 } 3456 RealHostAddr.sin6.sin6_port = port6; 3457 break; 3458 # endif /* NO_GETSERVBYNAME */ 3459 #endif /* NETINET6 */ 3460 default: 3461 /* no ident info */ 3462 goto noident; 3463 } 3464 3465 s = -1; 3466 if (setjmp(CtxAuthTimeout) != 0) 3467 { 3468 if (s >= 0) 3469 (void) close(s); 3470 goto noident; 3471 } 3472 3473 /* put a timeout around the whole thing */ 3474 ev = sm_setevent(TimeOuts.to_ident, authtimeout, 0); 3475 3476 3477 /* connect to foreign IDENT server using same address as SMTP socket */ 3478 s = socket(la.sa.sa_family, SOCK_STREAM, 0); 3479 if (s < 0) 3480 { 3481 sm_clrevent(ev); 3482 goto noident; 3483 } 3484 if (bind(s, &la.sa, lalen) < 0 || 3485 connect(s, &RealHostAddr.sa, lalen) < 0) 3486 goto closeident; 3487 3488 if (tTd(9, 10)) 3489 sm_dprintf("getauthinfo: sent %s", ibuf); 3490 3491 /* send query */ 3492 if (write(s, ibuf, strlen(ibuf)) < 0) 3493 goto closeident; 3494 3495 /* get result */ 3496 p = &ibuf[0]; 3497 nleft = sizeof ibuf - 1; 3498 while ((i = read(s, p, nleft)) > 0) 3499 { 3500 p += i; 3501 nleft -= i; 3502 *p = '\0'; 3503 if (strchr(ibuf, '\n') != NULL || nleft <= 0) 3504 break; 3505 } 3506 (void) close(s); 3507 sm_clrevent(ev); 3508 if (i < 0 || p == &ibuf[0]) 3509 goto noident; 3510 3511 if (*--p == '\n' && *--p == '\r') 3512 p--; 3513 *++p = '\0'; 3514 3515 if (tTd(9, 3)) 3516 sm_dprintf("getauthinfo: got %s\n", ibuf); 3517 3518 /* parse result */ 3519 p = strchr(ibuf, ':'); 3520 if (p == NULL) 3521 { 3522 /* malformed response */ 3523 goto noident; 3524 } 3525 while (isascii(*++p) && isspace(*p)) 3526 continue; 3527 if (sm_strncasecmp(p, "userid", 6) != 0) 3528 { 3529 /* presumably an error string */ 3530 goto noident; 3531 } 3532 p += 6; 3533 while (isascii(*p) && isspace(*p)) 3534 p++; 3535 if (*p++ != ':') 3536 { 3537 /* either useridxx or malformed response */ 3538 goto noident; 3539 } 3540 3541 /* p now points to the OSTYPE field */ 3542 while (isascii(*p) && isspace(*p)) 3543 p++; 3544 ostype = p; 3545 p = strchr(p, ':'); 3546 if (p == NULL) 3547 { 3548 /* malformed response */ 3549 goto noident; 3550 } 3551 else 3552 { 3553 char *charset; 3554 3555 *p = '\0'; 3556 charset = strchr(ostype, ','); 3557 if (charset != NULL) 3558 *charset = '\0'; 3559 } 3560 3561 /* 1413 says don't do this -- but it's broken otherwise */ 3562 while (isascii(*++p) && isspace(*p)) 3563 continue; 3564 3565 /* p now points to the authenticated name -- copy carefully */ 3566 if (sm_strncasecmp(ostype, "other", 5) == 0 && 3567 (ostype[5] == ' ' || ostype[5] == '\0')) 3568 { 3569 (void) sm_strlcpy(hbuf, "IDENT:", sizeof hbuf); 3570 cleanstrcpy(&hbuf[6], p, MAXNAME); 3571 } 3572 else 3573 cleanstrcpy(hbuf, p, MAXNAME); 3574 len = strlen(hbuf); 3575 (void) sm_strlcpyn(&hbuf[len], sizeof hbuf - len, 2, "@", 3576 RealHostName == NULL ? "localhost" : RealHostName); 3577 goto postident; 3578 3579 closeident: 3580 (void) close(s); 3581 sm_clrevent(ev); 3582 3583 noident: 3584 /* put back the original incoming port */ 3585 switch (RealHostAddr.sa.sa_family) 3586 { 3587 #if NETINET 3588 case AF_INET: 3589 if (port > 0) 3590 RealHostAddr.sin.sin_port = port; 3591 break; 3592 #endif /* NETINET */ 3593 3594 #if NETINET6 3595 case AF_INET6: 3596 if (port > 0) 3597 RealHostAddr.sin6.sin6_port = port; 3598 break; 3599 #endif /* NETINET6 */ 3600 } 3601 3602 if (RealHostName == NULL) 3603 { 3604 if (tTd(9, 1)) 3605 sm_dprintf("getauthinfo: NULL\n"); 3606 return NULL; 3607 } 3608 (void) sm_strlcpy(hbuf, RealHostName, sizeof hbuf); 3609 3610 postident: 3611 #if IP_SRCROUTE 3612 # ifndef GET_IPOPT_DST 3613 # define GET_IPOPT_DST(dst) (dst) 3614 # endif /* ! GET_IPOPT_DST */ 3615 /* 3616 ** Extract IP source routing information. 3617 ** 3618 ** Format of output for a connection from site a through b 3619 ** through c to d: 3620 ** loose: @site-c@site-b:site-a 3621 ** strict: !@site-c@site-b:site-a 3622 ** 3623 ** o - pointer within ipopt_list structure. 3624 ** q - pointer within ls/ss rr route data 3625 ** p - pointer to hbuf 3626 */ 3627 3628 if (RealHostAddr.sa.sa_family == AF_INET) 3629 { 3630 SOCKOPT_LEN_T ipoptlen; 3631 int j; 3632 unsigned char *q; 3633 unsigned char *o; 3634 int l; 3635 struct IPOPTION ipopt; 3636 3637 ipoptlen = sizeof ipopt; 3638 if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS, 3639 (char *) &ipopt, &ipoptlen) < 0) 3640 goto noipsr; 3641 if (ipoptlen == 0) 3642 goto noipsr; 3643 o = (unsigned char *) ipopt.IP_LIST; 3644 while (o != NULL && o < (unsigned char *) &ipopt + ipoptlen) 3645 { 3646 switch (*o) 3647 { 3648 case IPOPT_EOL: 3649 o = NULL; 3650 break; 3651 3652 case IPOPT_NOP: 3653 o++; 3654 break; 3655 3656 case IPOPT_SSRR: 3657 case IPOPT_LSRR: 3658 /* 3659 ** Source routing. 3660 ** o[0] is the option type (loose/strict). 3661 ** o[1] is the length of this option, 3662 ** including option type and 3663 ** length. 3664 ** o[2] is the pointer into the route 3665 ** data. 3666 ** o[3] begins the route data. 3667 */ 3668 3669 p = &hbuf[strlen(hbuf)]; 3670 l = sizeof hbuf - (hbuf - p) - 6; 3671 (void) sm_snprintf(p, SPACELEFT(hbuf, p), 3672 " [%s@%.*s", 3673 *o == IPOPT_SSRR ? "!" : "", 3674 l > 240 ? 120 : l / 2, 3675 inet_ntoa(GET_IPOPT_DST(ipopt.IP_DST))); 3676 i = strlen(p); 3677 p += i; 3678 l -= strlen(p); 3679 3680 j = o[1] / sizeof(struct in_addr) - 1; 3681 3682 /* q skips length and router pointer to data */ 3683 q = &o[3]; 3684 for ( ; j >= 0; j--) 3685 { 3686 struct in_addr addr; 3687 3688 memcpy(&addr, q, sizeof(addr)); 3689 (void) sm_snprintf(p, 3690 SPACELEFT(hbuf, p), 3691 "%c%.*s", 3692 j != 0 ? '@' : ':', 3693 l > 240 ? 120 : 3694 j == 0 ? l : l / 2, 3695 inet_ntoa(addr)); 3696 i = strlen(p); 3697 p += i; 3698 l -= i + 1; 3699 q += sizeof(struct in_addr); 3700 } 3701 o += o[1]; 3702 break; 3703 3704 default: 3705 /* Skip over option */ 3706 o += o[1]; 3707 break; 3708 } 3709 } 3710 (void) sm_snprintf(p, SPACELEFT(hbuf, p), "]"); 3711 goto postipsr; 3712 } 3713 3714 noipsr: 3715 #endif /* IP_SRCROUTE */ 3716 if (RealHostName != NULL && RealHostName[0] != '[') 3717 { 3718 p = &hbuf[strlen(hbuf)]; 3719 (void) sm_snprintf(p, SPACELEFT(hbuf, p), " [%.100s]", 3720 anynet_ntoa(&RealHostAddr)); 3721 } 3722 if (*may_be_forged) 3723 { 3724 p = &hbuf[strlen(hbuf)]; 3725 (void) sm_strlcpy(p, " (may be forged)", SPACELEFT(hbuf, p)); 3726 macdefine(&BlankEnvelope.e_macro, A_PERM, 3727 macid("{client_resolve}"), "FORGED"); 3728 } 3729 3730 #if IP_SRCROUTE 3731 postipsr: 3732 #endif /* IP_SRCROUTE */ 3733 3734 /* put back the original incoming port */ 3735 switch (RealHostAddr.sa.sa_family) 3736 { 3737 #if NETINET 3738 case AF_INET: 3739 if (port > 0) 3740 RealHostAddr.sin.sin_port = port; 3741 break; 3742 #endif /* NETINET */ 3743 3744 #if NETINET6 3745 case AF_INET6: 3746 if (port > 0) 3747 RealHostAddr.sin6.sin6_port = port; 3748 break; 3749 #endif /* NETINET6 */ 3750 } 3751 3752 if (tTd(9, 1)) 3753 sm_dprintf("getauthinfo: %s\n", hbuf); 3754 return hbuf; 3755 } 3756 /* 3757 ** HOST_MAP_LOOKUP -- turn a hostname into canonical form 3758 ** 3759 ** Parameters: 3760 ** map -- a pointer to this map. 3761 ** name -- the (presumably unqualified) hostname. 3762 ** av -- unused -- for compatibility with other mapping 3763 ** functions. 3764 ** statp -- an exit status (out parameter) -- set to 3765 ** EX_TEMPFAIL if the name server is unavailable. 3766 ** 3767 ** Returns: 3768 ** The mapping, if found. 3769 ** NULL if no mapping found. 3770 ** 3771 ** Side Effects: 3772 ** Looks up the host specified in hbuf. If it is not 3773 ** the canonical name for that host, return the canonical 3774 ** name (unless MF_MATCHONLY is set, which will cause the 3775 ** status only to be returned). 3776 */ 3777 3778 char * 3779 host_map_lookup(map, name, av, statp) 3780 MAP *map; 3781 char *name; 3782 char **av; 3783 int *statp; 3784 { 3785 register struct hostent *hp; 3786 #if NETINET 3787 struct in_addr in_addr; 3788 #endif /* NETINET */ 3789 #if NETINET6 3790 struct in6_addr in6_addr; 3791 #endif /* NETINET6 */ 3792 char *cp, *ans = NULL; 3793 register STAB *s; 3794 time_t now; 3795 #if NAMED_BIND 3796 time_t SM_NONVOLATILE retrans = 0; 3797 int SM_NONVOLATILE retry = 0; 3798 #endif /* NAMED_BIND */ 3799 char hbuf[MAXNAME + 1]; 3800 3801 /* 3802 ** See if we have already looked up this name. If so, just 3803 ** return it (unless expired). 3804 */ 3805 3806 now = curtime(); 3807 s = stab(name, ST_NAMECANON, ST_ENTER); 3808 if (bitset(NCF_VALID, s->s_namecanon.nc_flags) && 3809 s->s_namecanon.nc_exp >= now) 3810 { 3811 if (tTd(9, 1)) 3812 sm_dprintf("host_map_lookup(%s) => CACHE %s\n", 3813 name, 3814 s->s_namecanon.nc_cname == NULL 3815 ? "NULL" 3816 : s->s_namecanon.nc_cname); 3817 errno = s->s_namecanon.nc_errno; 3818 SM_SET_H_ERRNO(s->s_namecanon.nc_herrno); 3819 *statp = s->s_namecanon.nc_stat; 3820 if (*statp == EX_TEMPFAIL) 3821 { 3822 CurEnv->e_status = "4.4.3"; 3823 message("851 %s: Name server timeout", 3824 shortenstring(name, 33)); 3825 } 3826 if (*statp != EX_OK) 3827 return NULL; 3828 if (s->s_namecanon.nc_cname == NULL) 3829 { 3830 syserr("host_map_lookup(%s): bogus NULL cache entry, errno = %d, h_errno = %d", 3831 name, 3832 s->s_namecanon.nc_errno, 3833 s->s_namecanon.nc_herrno); 3834 return NULL; 3835 } 3836 if (bitset(MF_MATCHONLY, map->map_mflags)) 3837 cp = map_rewrite(map, name, strlen(name), NULL); 3838 else 3839 cp = map_rewrite(map, 3840 s->s_namecanon.nc_cname, 3841 strlen(s->s_namecanon.nc_cname), 3842 av); 3843 return cp; 3844 } 3845 3846 /* 3847 ** If we are running without a regular network connection (usually 3848 ** dial-on-demand) and we are just queueing, we want to avoid DNS 3849 ** lookups because those could try to connect to a server. 3850 */ 3851 3852 if (CurEnv->e_sendmode == SM_DEFER && 3853 bitset(MF_DEFER, map->map_mflags)) 3854 { 3855 if (tTd(9, 1)) 3856 sm_dprintf("host_map_lookup(%s) => DEFERRED\n", name); 3857 *statp = EX_TEMPFAIL; 3858 return NULL; 3859 } 3860 3861 /* 3862 ** If first character is a bracket, then it is an address 3863 ** lookup. Address is copied into a temporary buffer to 3864 ** strip the brackets and to preserve name if address is 3865 ** unknown. 3866 */ 3867 3868 if (tTd(9, 1)) 3869 sm_dprintf("host_map_lookup(%s) => ", name); 3870 #if NAMED_BIND 3871 if (map->map_timeout > 0) 3872 { 3873 retrans = _res.retrans; 3874 _res.retrans = map->map_timeout; 3875 } 3876 if (map->map_retry > 0) 3877 { 3878 retry = _res.retry; 3879 _res.retry = map->map_retry; 3880 } 3881 #endif /* NAMED_BIND */ 3882 3883 /* set default TTL */ 3884 s->s_namecanon.nc_exp = now + SM_DEFAULT_TTL; 3885 if (*name != '[') 3886 { 3887 int ttl; 3888 3889 (void) sm_strlcpy(hbuf, name, sizeof hbuf); 3890 if (getcanonname(hbuf, sizeof hbuf - 1, !HasWildcardMX, &ttl)) 3891 { 3892 ans = hbuf; 3893 if (ttl > 0) 3894 s->s_namecanon.nc_exp = now + SM_MIN(ttl, 3895 SM_DEFAULT_TTL); 3896 } 3897 } 3898 else 3899 { 3900 if ((cp = strchr(name, ']')) == NULL) 3901 { 3902 if (tTd(9, 1)) 3903 sm_dprintf("FAILED\n"); 3904 return NULL; 3905 } 3906 *cp = '\0'; 3907 3908 hp = NULL; 3909 #if NETINET 3910 if ((in_addr.s_addr = inet_addr(&name[1])) != INADDR_NONE) 3911 hp = sm_gethostbyaddr((char *)&in_addr, 3912 INADDRSZ, AF_INET); 3913 #endif /* NETINET */ 3914 #if NETINET6 3915 if (hp == NULL && 3916 anynet_pton(AF_INET6, &name[1], &in6_addr) == 1) 3917 hp = sm_gethostbyaddr((char *)&in6_addr, 3918 IN6ADDRSZ, AF_INET6); 3919 #endif /* NETINET6 */ 3920 *cp = ']'; 3921 3922 if (hp != NULL) 3923 { 3924 /* found a match -- copy out */ 3925 ans = denlstring((char *) hp->h_name, true, true); 3926 #if NETINET6 3927 if (ans == hp->h_name) 3928 { 3929 static char n[MAXNAME + 1]; 3930 3931 /* hp->h_name is about to disappear */ 3932 (void) sm_strlcpy(n, ans, sizeof n); 3933 ans = n; 3934 } 3935 freehostent(hp); 3936 hp = NULL; 3937 #endif /* NETINET6 */ 3938 } 3939 } 3940 #if NAMED_BIND 3941 if (map->map_timeout > 0) 3942 _res.retrans = retrans; 3943 if (map->map_retry > 0) 3944 _res.retry = retry; 3945 #endif /* NAMED_BIND */ 3946 3947 s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */ 3948 3949 /* Found an answer */ 3950 if (ans != NULL) 3951 { 3952 s->s_namecanon.nc_stat = *statp = EX_OK; 3953 if (s->s_namecanon.nc_cname != NULL) 3954 sm_free(s->s_namecanon.nc_cname); 3955 s->s_namecanon.nc_cname = sm_strdup_x(ans); 3956 if (bitset(MF_MATCHONLY, map->map_mflags)) 3957 cp = map_rewrite(map, name, strlen(name), NULL); 3958 else 3959 cp = map_rewrite(map, ans, strlen(ans), av); 3960 if (tTd(9, 1)) 3961 sm_dprintf("FOUND %s\n", ans); 3962 return cp; 3963 } 3964 3965 3966 /* No match found */ 3967 s->s_namecanon.nc_errno = errno; 3968 #if NAMED_BIND 3969 s->s_namecanon.nc_herrno = h_errno; 3970 if (tTd(9, 1)) 3971 sm_dprintf("FAIL (%d)\n", h_errno); 3972 switch (h_errno) 3973 { 3974 case TRY_AGAIN: 3975 if (UseNameServer) 3976 { 3977 CurEnv->e_status = "4.4.3"; 3978 message("851 %s: Name server timeout", 3979 shortenstring(name, 33)); 3980 } 3981 *statp = EX_TEMPFAIL; 3982 break; 3983 3984 case HOST_NOT_FOUND: 3985 case NO_DATA: 3986 *statp = EX_NOHOST; 3987 break; 3988 3989 case NO_RECOVERY: 3990 *statp = EX_SOFTWARE; 3991 break; 3992 3993 default: 3994 *statp = EX_UNAVAILABLE; 3995 break; 3996 } 3997 #else /* NAMED_BIND */ 3998 if (tTd(9, 1)) 3999 sm_dprintf("FAIL\n"); 4000 *statp = EX_NOHOST; 4001 #endif /* NAMED_BIND */ 4002 s->s_namecanon.nc_stat = *statp; 4003 return NULL; 4004 } 4005 /* 4006 ** HOST_MAP_INIT -- initialize host class structures 4007 ** 4008 ** Parameters: 4009 ** map -- a pointer to this map. 4010 ** args -- argument string. 4011 ** 4012 ** Returns: 4013 ** true. 4014 */ 4015 4016 bool 4017 host_map_init(map, args) 4018 MAP *map; 4019 char *args; 4020 { 4021 register char *p = args; 4022 4023 for (;;) 4024 { 4025 while (isascii(*p) && isspace(*p)) 4026 p++; 4027 if (*p != '-') 4028 break; 4029 switch (*++p) 4030 { 4031 case 'a': 4032 map->map_app = ++p; 4033 break; 4034 4035 case 'T': 4036 map->map_tapp = ++p; 4037 break; 4038 4039 case 'm': 4040 map->map_mflags |= MF_MATCHONLY; 4041 break; 4042 4043 case 't': 4044 map->map_mflags |= MF_NODEFER; 4045 break; 4046 4047 case 'S': /* only for consistency */ 4048 map->map_spacesub = *++p; 4049 break; 4050 4051 case 'D': 4052 map->map_mflags |= MF_DEFER; 4053 break; 4054 4055 case 'd': 4056 { 4057 char *h; 4058 4059 while (isascii(*++p) && isspace(*p)) 4060 continue; 4061 h = strchr(p, ' '); 4062 if (h != NULL) 4063 *h = '\0'; 4064 map->map_timeout = convtime(p, 's'); 4065 if (h != NULL) 4066 *h = ' '; 4067 } 4068 break; 4069 4070 case 'r': 4071 while (isascii(*++p) && isspace(*p)) 4072 continue; 4073 map->map_retry = atoi(p); 4074 break; 4075 } 4076 while (*p != '\0' && !(isascii(*p) && isspace(*p))) 4077 p++; 4078 if (*p != '\0') 4079 *p++ = '\0'; 4080 } 4081 if (map->map_app != NULL) 4082 map->map_app = newstr(map->map_app); 4083 if (map->map_tapp != NULL) 4084 map->map_tapp = newstr(map->map_tapp); 4085 return true; 4086 } 4087 4088 #if NETINET6 4089 /* 4090 ** ANYNET_NTOP -- convert an IPv6 network address to printable form. 4091 ** 4092 ** Parameters: 4093 ** s6a -- a pointer to an in6_addr structure. 4094 ** dst -- buffer to store result in 4095 ** dst_len -- size of dst buffer 4096 ** 4097 ** Returns: 4098 ** A printable version of that structure. 4099 */ 4100 4101 char * 4102 anynet_ntop(s6a, dst, dst_len) 4103 struct in6_addr *s6a; 4104 char *dst; 4105 size_t dst_len; 4106 { 4107 register char *ap; 4108 4109 if (IN6_IS_ADDR_V4MAPPED(s6a)) 4110 ap = (char *) inet_ntop(AF_INET, 4111 &s6a->s6_addr[IN6ADDRSZ - INADDRSZ], 4112 dst, dst_len); 4113 else 4114 { 4115 char *d; 4116 size_t sz; 4117 4118 /* Save pointer to beginning of string */ 4119 d = dst; 4120 4121 /* Add IPv6: protocol tag */ 4122 sz = sm_strlcpy(dst, "IPv6:", dst_len); 4123 if (sz >= dst_len) 4124 return NULL; 4125 dst += sz; 4126 dst_len -= sz; 4127 ap = (char *) inet_ntop(AF_INET6, s6a, dst, dst_len); 4128 4129 /* Restore pointer to beginning of string */ 4130 if (ap != NULL) 4131 ap = d; 4132 } 4133 return ap; 4134 } 4135 4136 /* 4137 ** ANYNET_PTON -- convert printed form to network address. 4138 ** 4139 ** Wrapper for inet_pton() which handles IPv6: labels. 4140 ** 4141 ** Parameters: 4142 ** family -- address family 4143 ** src -- string 4144 ** dst -- destination address structure 4145 ** 4146 ** Returns: 4147 ** 1 if the address was valid 4148 ** 0 if the address wasn't parseable 4149 ** -1 if error 4150 */ 4151 4152 int 4153 anynet_pton(family, src, dst) 4154 int family; 4155 const char *src; 4156 void *dst; 4157 { 4158 if (family == AF_INET6 && sm_strncasecmp(src, "IPv6:", 5) == 0) 4159 src += 5; 4160 return inet_pton(family, src, dst); 4161 } 4162 #endif /* NETINET6 */ 4163 /* 4164 ** ANYNET_NTOA -- convert a network address to printable form. 4165 ** 4166 ** Parameters: 4167 ** sap -- a pointer to a sockaddr structure. 4168 ** 4169 ** Returns: 4170 ** A printable version of that sockaddr. 4171 */ 4172 4173 #ifdef USE_SOCK_STREAM 4174 4175 # if NETLINK 4176 # include <net/if_dl.h> 4177 # endif /* NETLINK */ 4178 4179 char * 4180 anynet_ntoa(sap) 4181 register SOCKADDR *sap; 4182 { 4183 register char *bp; 4184 register char *ap; 4185 int l; 4186 static char buf[100]; 4187 4188 /* check for null/zero family */ 4189 if (sap == NULL) 4190 return "NULLADDR"; 4191 if (sap->sa.sa_family == 0) 4192 return "0"; 4193 4194 switch (sap->sa.sa_family) 4195 { 4196 # if NETUNIX 4197 case AF_UNIX: 4198 if (sap->sunix.sun_path[0] != '\0') 4199 (void) sm_snprintf(buf, sizeof buf, "[UNIX: %.64s]", 4200 sap->sunix.sun_path); 4201 else 4202 (void) sm_strlcpy(buf, "[UNIX: localhost]", sizeof buf); 4203 return buf; 4204 # endif /* NETUNIX */ 4205 4206 # if NETINET 4207 case AF_INET: 4208 return (char *) inet_ntoa(sap->sin.sin_addr); 4209 # endif /* NETINET */ 4210 4211 # if NETINET6 4212 case AF_INET6: 4213 ap = anynet_ntop(&sap->sin6.sin6_addr, buf, sizeof buf); 4214 if (ap != NULL) 4215 return ap; 4216 break; 4217 # endif /* NETINET6 */ 4218 4219 # if NETLINK 4220 case AF_LINK: 4221 (void) sm_snprintf(buf, sizeof buf, "[LINK: %s]", 4222 link_ntoa((struct sockaddr_dl *) &sap->sa)); 4223 return buf; 4224 # endif /* NETLINK */ 4225 default: 4226 /* this case is needed when nothing is #defined */ 4227 /* in order to keep the switch syntactically correct */ 4228 break; 4229 } 4230 4231 /* unknown family -- just dump bytes */ 4232 (void) sm_snprintf(buf, sizeof buf, "Family %d: ", sap->sa.sa_family); 4233 bp = &buf[strlen(buf)]; 4234 ap = sap->sa.sa_data; 4235 for (l = sizeof sap->sa.sa_data; --l >= 0; ) 4236 { 4237 (void) sm_snprintf(bp, SPACELEFT(buf, bp), "%02x:", 4238 *ap++ & 0377); 4239 bp += 3; 4240 } 4241 *--bp = '\0'; 4242 return buf; 4243 } 4244 /* 4245 ** HOSTNAMEBYANYADDR -- return name of host based on address 4246 ** 4247 ** Parameters: 4248 ** sap -- SOCKADDR pointer 4249 ** 4250 ** Returns: 4251 ** text representation of host name. 4252 ** 4253 ** Side Effects: 4254 ** none. 4255 */ 4256 4257 char * 4258 hostnamebyanyaddr(sap) 4259 register SOCKADDR *sap; 4260 { 4261 register struct hostent *hp; 4262 # if NAMED_BIND 4263 int saveretry; 4264 # endif /* NAMED_BIND */ 4265 # if NETINET6 4266 struct in6_addr in6_addr; 4267 # endif /* NETINET6 */ 4268 4269 # if NAMED_BIND 4270 /* shorten name server timeout to avoid higher level timeouts */ 4271 saveretry = _res.retry; 4272 if (_res.retry * _res.retrans > 20) 4273 _res.retry = 20 / _res.retrans; 4274 # endif /* NAMED_BIND */ 4275 4276 switch (sap->sa.sa_family) 4277 { 4278 # if NETINET 4279 case AF_INET: 4280 hp = sm_gethostbyaddr((char *) &sap->sin.sin_addr, 4281 INADDRSZ, AF_INET); 4282 break; 4283 # endif /* NETINET */ 4284 4285 # if NETINET6 4286 case AF_INET6: 4287 hp = sm_gethostbyaddr((char *) &sap->sin6.sin6_addr, 4288 IN6ADDRSZ, AF_INET6); 4289 break; 4290 # endif /* NETINET6 */ 4291 4292 # if NETISO 4293 case AF_ISO: 4294 hp = sm_gethostbyaddr((char *) &sap->siso.siso_addr, 4295 sizeof sap->siso.siso_addr, AF_ISO); 4296 break; 4297 # endif /* NETISO */ 4298 4299 # if NETUNIX 4300 case AF_UNIX: 4301 hp = NULL; 4302 break; 4303 # endif /* NETUNIX */ 4304 4305 default: 4306 hp = sm_gethostbyaddr(sap->sa.sa_data, sizeof sap->sa.sa_data, 4307 sap->sa.sa_family); 4308 break; 4309 } 4310 4311 # if NAMED_BIND 4312 _res.retry = saveretry; 4313 # endif /* NAMED_BIND */ 4314 4315 # if NETINET || NETINET6 4316 if (hp != NULL && hp->h_name[0] != '[' 4317 # if NETINET6 4318 && inet_pton(AF_INET6, hp->h_name, &in6_addr) != 1 4319 # endif /* NETINET6 */ 4320 # if NETINET 4321 && inet_addr(hp->h_name) == INADDR_NONE 4322 # endif /* NETINET */ 4323 ) 4324 { 4325 char *name; 4326 4327 name = denlstring((char *) hp->h_name, true, true); 4328 # if NETINET6 4329 if (name == hp->h_name) 4330 { 4331 static char n[MAXNAME + 1]; 4332 4333 /* Copy the string, hp->h_name is about to disappear */ 4334 (void) sm_strlcpy(n, name, sizeof n); 4335 name = n; 4336 } 4337 freehostent(hp); 4338 # endif /* NETINET6 */ 4339 return name; 4340 } 4341 # endif /* NETINET || NETINET6 */ 4342 4343 # if NETINET6 4344 if (hp != NULL) 4345 { 4346 freehostent(hp); 4347 hp = NULL; 4348 } 4349 # endif /* NETINET6 */ 4350 4351 # if NETUNIX 4352 if (sap->sa.sa_family == AF_UNIX && sap->sunix.sun_path[0] == '\0') 4353 return "localhost"; 4354 # endif /* NETUNIX */ 4355 { 4356 static char buf[203]; 4357 4358 (void) sm_snprintf(buf, sizeof buf, "[%.200s]", 4359 anynet_ntoa(sap)); 4360 return buf; 4361 } 4362 } 4363 #endif /* USE_SOCK_STREAM */ 4364