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