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