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