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