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