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