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