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