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