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