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