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