1 /* 2 * Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14 #include <sendmail.h> 15 16 SM_RCSID("@(#)$Id: daemon.c,v 8.666 2006/04/18 01:23:42 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 <sm/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 static void connecttimeout __P((int)); 94 static int opendaemonsocket __P((DAEMON_T *, bool)); 95 static unsigned short setupdaemon __P((SOCKADDR *)); 96 static void getrequests_checkdiskspace __P((ENVELOPE *e)); 97 static void setsockaddroptions __P((char *, DAEMON_T *)); 98 static void printdaemonflags __P((DAEMON_T *)); 99 static int addr_family __P((char *)); 100 static int addrcmp __P((struct hostent *, char *, SOCKADDR *)); 101 static void authtimeout __P((int)); 102 103 /* 104 ** DAEMON.C -- routines to use when running as a daemon. 105 ** 106 ** This entire file is highly dependent on the 4.2 BSD 107 ** interprocess communication primitives. No attempt has 108 ** been made to make this file portable to Version 7, 109 ** Version 6, MPX files, etc. If you should try such a 110 ** thing yourself, I recommend chucking the entire file 111 ** and starting from scratch. Basic semantics are: 112 ** 113 ** getrequests(e) 114 ** Opens a port and initiates a connection. 115 ** Returns in a child. Must set InChannel and 116 ** OutChannel appropriately. 117 ** clrdaemon() 118 ** Close any open files associated with getting 119 ** the connection; this is used when running the queue, 120 ** etc., to avoid having extra file descriptors during 121 ** the queue run and to avoid confusing the network 122 ** code (if it cares). 123 ** makeconnection(host, port, mci, e, enough) 124 ** Make a connection to the named host on the given 125 ** port. Returns zero on success, else an exit status 126 ** describing the error. 127 ** host_map_lookup(map, hbuf, avp, pstat) 128 ** Convert the entry in hbuf into a canonical form. 129 */ 130 131 static DAEMON_T Daemons[MAXDAEMONS]; 132 static int NDaemons = 0; /* actual number of daemons */ 133 134 static time_t NextDiskSpaceCheck = 0; 135 136 /* 137 ** GETREQUESTS -- open mail IPC port and get requests. 138 ** 139 ** Parameters: 140 ** e -- the current envelope. 141 ** 142 ** Returns: 143 ** pointer to flags. 144 ** 145 ** Side Effects: 146 ** Waits until some interesting activity occurs. When 147 ** it does, a child is created to process it, and the 148 ** parent waits for completion. Return from this 149 ** routine is always in the child. The file pointers 150 ** "InChannel" and "OutChannel" should be set to point 151 ** to the communication channel. 152 ** May restart persistent queue runners if they have ended 153 ** for some reason. 154 */ 155 156 BITMAP256 * 157 getrequests(e) 158 ENVELOPE *e; 159 { 160 int t; 161 int idx, curdaemon = -1; 162 int i, olddaemon = 0; 163 #if XDEBUG 164 bool j_has_dot; 165 #endif /* XDEBUG */ 166 char status[MAXLINE]; 167 SOCKADDR sa; 168 SOCKADDR_LEN_T len = sizeof sa; 169 #if _FFR_QUEUE_RUN_PARANOIA 170 time_t lastrun; 171 #endif /* _FFR_QUEUE_RUN_PARANOIA */ 172 # if NETUNIX 173 extern int ControlSocket; 174 # endif /* NETUNIX */ 175 extern ENVELOPE BlankEnvelope; 176 extern bool refuseconnections __P((char *, ENVELOPE *, int, bool)); 177 178 179 /* initialize data for function that generates queue ids */ 180 init_qid_alg(); 181 for (idx = 0; idx < NDaemons; idx++) 182 { 183 Daemons[idx].d_port = setupdaemon(&(Daemons[idx].d_addr)); 184 Daemons[idx].d_firsttime = true; 185 Daemons[idx].d_refuse_connections_until = (time_t) 0; 186 } 187 188 /* 189 ** Try to actually open the connection. 190 */ 191 192 if (tTd(15, 1)) 193 { 194 for (idx = 0; idx < NDaemons; idx++) 195 { 196 sm_dprintf("getrequests: daemon %s: port %d\n", 197 Daemons[idx].d_name, 198 ntohs(Daemons[idx].d_port)); 199 } 200 } 201 202 /* get a socket for the SMTP connection */ 203 for (idx = 0; idx < NDaemons; idx++) 204 Daemons[idx].d_socksize = opendaemonsocket(&Daemons[idx], true); 205 206 if (opencontrolsocket() < 0) 207 sm_syslog(LOG_WARNING, NOQID, 208 "daemon could not open control socket %s: %s", 209 ControlSocketName, sm_errstring(errno)); 210 211 /* If there are any queue runners released reapchild() co-ord's */ 212 (void) sm_signal(SIGCHLD, reapchild); 213 214 /* write the pid to file, command line args to syslog */ 215 log_sendmail_pid(e); 216 217 #if XDEBUG 218 { 219 char jbuf[MAXHOSTNAMELEN]; 220 221 expand("\201j", jbuf, sizeof jbuf, e); 222 j_has_dot = strchr(jbuf, '.') != NULL; 223 } 224 #endif /* XDEBUG */ 225 226 /* Add parent process as first item */ 227 proc_list_add(CurrentPid, "Sendmail daemon", PROC_DAEMON, 0, -1, NULL); 228 229 if (tTd(15, 1)) 230 { 231 for (idx = 0; idx < NDaemons; idx++) 232 sm_dprintf("getrequests: daemon %s: %d\n", 233 Daemons[idx].d_name, 234 Daemons[idx].d_socket); 235 } 236 237 for (;;) 238 { 239 register pid_t pid; 240 auto SOCKADDR_LEN_T lotherend; 241 bool timedout = false; 242 bool control = false; 243 int save_errno; 244 int pipefd[2]; 245 time_t now; 246 #if STARTTLS 247 long seed; 248 #endif /* STARTTLS */ 249 250 /* see if we are rejecting connections */ 251 (void) sm_blocksignal(SIGALRM); 252 CHECK_RESTART; 253 254 for (idx = 0; idx < NDaemons; idx++) 255 { 256 /* 257 ** XXX do this call outside the loop? 258 ** no: refuse_connections may sleep(). 259 */ 260 261 now = curtime(); 262 if (now < Daemons[idx].d_refuse_connections_until) 263 continue; 264 if (bitnset(D_DISABLE, Daemons[idx].d_flags)) 265 continue; 266 if (refuseconnections(Daemons[idx].d_name, e, idx, 267 curdaemon == idx)) 268 { 269 if (Daemons[idx].d_socket >= 0) 270 { 271 /* close socket so peer fails quickly */ 272 (void) close(Daemons[idx].d_socket); 273 Daemons[idx].d_socket = -1; 274 } 275 276 /* refuse connections for next 15 seconds */ 277 Daemons[idx].d_refuse_connections_until = now + 15; 278 } 279 else if (Daemons[idx].d_socket < 0 || 280 Daemons[idx].d_firsttime) 281 { 282 if (!Daemons[idx].d_firsttime && LogLevel > 8) 283 sm_syslog(LOG_INFO, NOQID, 284 "accepting connections again for daemon %s", 285 Daemons[idx].d_name); 286 287 /* arrange to (re)open the socket if needed */ 288 (void) opendaemonsocket(&Daemons[idx], false); 289 Daemons[idx].d_firsttime = false; 290 } 291 } 292 293 /* May have been sleeping above, check again */ 294 CHECK_RESTART; 295 296 getrequests_checkdiskspace(e); 297 298 #if XDEBUG 299 /* check for disaster */ 300 { 301 char jbuf[MAXHOSTNAMELEN]; 302 303 expand("\201j", jbuf, sizeof jbuf, e); 304 if (!wordinclass(jbuf, 'w')) 305 { 306 dumpstate("daemon lost $j"); 307 sm_syslog(LOG_ALERT, NOQID, 308 "daemon process doesn't have $j in $=w; see syslog"); 309 abort(); 310 } 311 else if (j_has_dot && strchr(jbuf, '.') == NULL) 312 { 313 dumpstate("daemon $j lost dot"); 314 sm_syslog(LOG_ALERT, NOQID, 315 "daemon process $j lost dot; see syslog"); 316 abort(); 317 } 318 } 319 #endif /* XDEBUG */ 320 321 #if 0 322 /* 323 ** Andrew Sun <asun@ieps-sun.ml.com> claims that this will 324 ** fix the SVr4 problem. But it seems to have gone away, 325 ** so is it worth doing this? 326 */ 327 328 if (DaemonSocket >= 0 && 329 SetNonBlocking(DaemonSocket, false) < 0) 330 log an error here; 331 #endif /* 0 */ 332 (void) sm_releasesignal(SIGALRM); 333 334 for (;;) 335 { 336 bool setproc = false; 337 int highest = -1; 338 fd_set readfds; 339 struct timeval timeout; 340 341 CHECK_RESTART; 342 FD_ZERO(&readfds); 343 for (idx = 0; idx < NDaemons; idx++) 344 { 345 /* wait for a connection */ 346 if (Daemons[idx].d_socket >= 0) 347 { 348 if (!setproc && 349 !bitnset(D_ETRNONLY, 350 Daemons[idx].d_flags)) 351 { 352 sm_setproctitle(true, e, 353 "accepting connections"); 354 setproc = true; 355 } 356 if (Daemons[idx].d_socket > highest) 357 highest = Daemons[idx].d_socket; 358 SM_FD_SET(Daemons[idx].d_socket, 359 &readfds); 360 } 361 } 362 363 #if NETUNIX 364 if (ControlSocket >= 0) 365 { 366 if (ControlSocket > highest) 367 highest = ControlSocket; 368 SM_FD_SET(ControlSocket, &readfds); 369 } 370 #endif /* NETUNIX */ 371 372 timeout.tv_sec = 5; 373 timeout.tv_usec = 0; 374 375 t = select(highest + 1, FDSET_CAST &readfds, 376 NULL, NULL, &timeout); 377 378 /* Did someone signal while waiting? */ 379 CHECK_RESTART; 380 381 curdaemon = -1; 382 if (doqueuerun()) 383 { 384 (void) runqueue(true, false, false, false); 385 #if _FFR_QUEUE_RUN_PARANOIA 386 lastrun = now; 387 #endif /* _FFR_QUEUE_RUN_PARANOIA */ 388 } 389 #if _FFR_QUEUE_RUN_PARANOIA 390 else if (CheckQueueRunners > 0 && QueueIntvl > 0 && 391 lastrun + QueueIntvl + CheckQueueRunners < now) 392 { 393 394 /* 395 ** set lastrun unconditionally to avoid 396 ** calling checkqueuerunner() all the time. 397 ** That's also why we currently ignore the 398 ** result of the function call. 399 */ 400 401 (void) checkqueuerunner(); 402 lastrun = now; 403 } 404 #endif /* _FFR_QUEUE_RUN_PARANOIA */ 405 406 if (t <= 0) 407 { 408 timedout = true; 409 break; 410 } 411 412 control = false; 413 errno = 0; 414 415 /* look "round-robin" for an active socket */ 416 if ((idx = olddaemon + 1) >= NDaemons) 417 idx = 0; 418 for (i = 0; i < NDaemons; i++) 419 { 420 if (Daemons[idx].d_socket >= 0 && 421 SM_FD_ISSET(Daemons[idx].d_socket, 422 &readfds)) 423 { 424 lotherend = Daemons[idx].d_socksize; 425 memset(&RealHostAddr, '\0', 426 sizeof RealHostAddr); 427 t = accept(Daemons[idx].d_socket, 428 (struct sockaddr *)&RealHostAddr, 429 &lotherend); 430 431 /* 432 ** If remote side closes before 433 ** accept() finishes, sockaddr 434 ** might not be fully filled in. 435 */ 436 437 if (t >= 0 && 438 (lotherend == 0 || 439 # ifdef BSD4_4_SOCKADDR 440 RealHostAddr.sa.sa_len == 0 || 441 # endif /* BSD4_4_SOCKADDR */ 442 RealHostAddr.sa.sa_family != Daemons[idx].d_addr.sa.sa_family)) 443 { 444 (void) close(t); 445 t = -1; 446 errno = EINVAL; 447 } 448 olddaemon = curdaemon = idx; 449 break; 450 } 451 if (++idx >= NDaemons) 452 idx = 0; 453 } 454 #if NETUNIX 455 if (curdaemon == -1 && ControlSocket >= 0 && 456 SM_FD_ISSET(ControlSocket, &readfds)) 457 { 458 struct sockaddr_un sa_un; 459 460 lotherend = sizeof sa_un; 461 memset(&sa_un, '\0', sizeof sa_un); 462 t = accept(ControlSocket, 463 (struct sockaddr *)&sa_un, 464 &lotherend); 465 466 /* 467 ** If remote side closes before 468 ** accept() finishes, sockaddr 469 ** might not be fully filled in. 470 */ 471 472 if (t >= 0 && 473 (lotherend == 0 || 474 # ifdef BSD4_4_SOCKADDR 475 sa_un.sun_len == 0 || 476 # endif /* BSD4_4_SOCKADDR */ 477 sa_un.sun_family != AF_UNIX)) 478 { 479 (void) close(t); 480 t = -1; 481 errno = EINVAL; 482 } 483 if (t >= 0) 484 control = true; 485 } 486 #else /* NETUNIX */ 487 if (curdaemon == -1) 488 { 489 /* No daemon to service */ 490 continue; 491 } 492 #endif /* NETUNIX */ 493 if (t >= 0 || errno != EINTR) 494 break; 495 } 496 if (timedout) 497 { 498 timedout = false; 499 continue; 500 } 501 save_errno = errno; 502 (void) sm_blocksignal(SIGALRM); 503 if (t < 0) 504 { 505 errno = save_errno; 506 507 /* let's ignore these temporary errors */ 508 if (save_errno == EINTR 509 #ifdef EAGAIN 510 || save_errno == EAGAIN 511 #endif /* EAGAIN */ 512 #ifdef ECONNABORTED 513 || save_errno == ECONNABORTED 514 #endif /* ECONNABORTED */ 515 #ifdef EWOULDBLOCK 516 || save_errno == EWOULDBLOCK 517 #endif /* EWOULDBLOCK */ 518 ) 519 continue; 520 521 syserr("getrequests: accept"); 522 523 if (curdaemon >= 0) 524 { 525 /* arrange to re-open socket next time around */ 526 (void) close(Daemons[curdaemon].d_socket); 527 Daemons[curdaemon].d_socket = -1; 528 #if SO_REUSEADDR_IS_BROKEN 529 /* 530 ** Give time for bound socket to be released. 531 ** This creates a denial-of-service if you can 532 ** force accept() to fail on affected systems. 533 */ 534 535 Daemons[curdaemon].d_refuse_connections_until = 536 curtime() + 15; 537 #endif /* SO_REUSEADDR_IS_BROKEN */ 538 } 539 continue; 540 } 541 542 if (!control) 543 { 544 /* set some daemon related macros */ 545 switch (Daemons[curdaemon].d_addr.sa.sa_family) 546 { 547 case AF_UNSPEC: 548 macdefine(&BlankEnvelope.e_macro, A_PERM, 549 macid("{daemon_family}"), "unspec"); 550 break; 551 #if _FFR_DAEMON_NETUNIX 552 # if NETUNIX 553 case AF_UNIX: 554 macdefine(&BlankEnvelope.e_macro, A_PERM, 555 macid("{daemon_family}"), "local"); 556 break; 557 # endif /* NETUNIX */ 558 #endif /* _FFR_DAEMON_NETUNIX */ 559 #if NETINET 560 case AF_INET: 561 macdefine(&BlankEnvelope.e_macro, A_PERM, 562 macid("{daemon_family}"), "inet"); 563 break; 564 #endif /* NETINET */ 565 #if NETINET6 566 case AF_INET6: 567 macdefine(&BlankEnvelope.e_macro, A_PERM, 568 macid("{daemon_family}"), "inet6"); 569 break; 570 #endif /* NETINET6 */ 571 #if NETISO 572 case AF_ISO: 573 macdefine(&BlankEnvelope.e_macro, A_PERM, 574 macid("{daemon_family}"), "iso"); 575 break; 576 #endif /* NETISO */ 577 #if NETNS 578 case AF_NS: 579 macdefine(&BlankEnvelope.e_macro, A_PERM, 580 macid("{daemon_family}"), "ns"); 581 break; 582 #endif /* NETNS */ 583 #if NETX25 584 case AF_CCITT: 585 macdefine(&BlankEnvelope.e_macro, A_PERM, 586 macid("{daemon_family}"), "x.25"); 587 break; 588 #endif /* NETX25 */ 589 } 590 macdefine(&BlankEnvelope.e_macro, A_PERM, 591 macid("{daemon_name}"), 592 Daemons[curdaemon].d_name); 593 if (Daemons[curdaemon].d_mflags != NULL) 594 macdefine(&BlankEnvelope.e_macro, A_PERM, 595 macid("{daemon_flags}"), 596 Daemons[curdaemon].d_mflags); 597 else 598 macdefine(&BlankEnvelope.e_macro, A_PERM, 599 macid("{daemon_flags}"), ""); 600 } 601 602 /* 603 ** If connection rate is exceeded here, connection shall be 604 ** refused later by a new call after fork() by the 605 ** validate_connection() function. Closing the connection 606 ** at this point violates RFC 2821. 607 ** Do NOT remove this call, its side effects are needed. 608 */ 609 610 connection_rate_check(&RealHostAddr, NULL); 611 612 /* 613 ** Create a subprocess to process the mail. 614 */ 615 616 if (tTd(15, 2)) 617 sm_dprintf("getrequests: forking (fd = %d)\n", t); 618 619 /* 620 ** Advance state of PRNG. 621 ** This is necessary because otherwise all child processes 622 ** will produce the same PRN sequence and hence the selection 623 ** of a queue directory (and other things, e.g., MX selection) 624 ** are not "really" random. 625 */ 626 #if STARTTLS 627 /* XXX get some better "random" data? */ 628 seed = get_random(); 629 RAND_seed((void *) &NextDiskSpaceCheck, 630 sizeof NextDiskSpaceCheck); 631 RAND_seed((void *) &now, sizeof now); 632 RAND_seed((void *) &seed, sizeof seed); 633 #else /* STARTTLS */ 634 (void) get_random(); 635 #endif /* STARTTLS */ 636 637 #if NAMED_BIND 638 /* 639 ** Update MX records for FallbackMX. 640 ** Let's hope this is fast otherwise we screw up the 641 ** response time. 642 */ 643 644 if (FallbackMX != NULL) 645 (void) getfallbackmxrr(FallbackMX); 646 #endif /* NAMED_BIND */ 647 648 if (tTd(93, 100)) 649 { 650 /* don't fork, handle connection in this process */ 651 pid = 0; 652 pipefd[0] = pipefd[1] = -1; 653 } 654 else 655 { 656 /* 657 ** Create a pipe to keep the child from writing to 658 ** the socket until after the parent has closed 659 ** it. Otherwise the parent may hang if the child 660 ** has closed it first. 661 */ 662 663 if (pipe(pipefd) < 0) 664 pipefd[0] = pipefd[1] = -1; 665 666 (void) sm_blocksignal(SIGCHLD); 667 pid = fork(); 668 if (pid < 0) 669 { 670 syserr("daemon: cannot fork"); 671 if (pipefd[0] != -1) 672 { 673 (void) close(pipefd[0]); 674 (void) close(pipefd[1]); 675 } 676 (void) sm_releasesignal(SIGCHLD); 677 (void) sleep(10); 678 (void) close(t); 679 continue; 680 } 681 } 682 683 if (pid == 0) 684 { 685 char *p; 686 SM_FILE_T *inchannel, *outchannel = NULL; 687 688 /* 689 ** CHILD -- return to caller. 690 ** Collect verified idea of sending host. 691 ** Verify calling user id if possible here. 692 */ 693 694 /* Reset global flags */ 695 RestartRequest = NULL; 696 RestartWorkGroup = false; 697 ShutdownRequest = NULL; 698 PendingSignal = 0; 699 CurrentPid = getpid(); 700 close_sendmail_pid(); 701 702 (void) sm_releasesignal(SIGALRM); 703 (void) sm_releasesignal(SIGCHLD); 704 (void) sm_signal(SIGCHLD, SIG_DFL); 705 (void) sm_signal(SIGHUP, SIG_DFL); 706 (void) sm_signal(SIGTERM, intsig); 707 708 /* turn on profiling */ 709 /* SM_PROF(0); */ 710 711 /* 712 ** Initialize exception stack and default exception 713 ** handler for child process. 714 */ 715 716 sm_exc_newthread(fatal_error); 717 718 if (!control) 719 { 720 macdefine(&BlankEnvelope.e_macro, A_TEMP, 721 macid("{daemon_addr}"), 722 anynet_ntoa(&Daemons[curdaemon].d_addr)); 723 (void) sm_snprintf(status, sizeof status, "%d", 724 ntohs(Daemons[curdaemon].d_port)); 725 macdefine(&BlankEnvelope.e_macro, A_TEMP, 726 macid("{daemon_port}"), status); 727 } 728 729 for (idx = 0; idx < NDaemons; idx++) 730 { 731 if (Daemons[idx].d_socket >= 0) 732 (void) close(Daemons[idx].d_socket); 733 Daemons[idx].d_socket = -1; 734 } 735 clrcontrol(); 736 737 /* Avoid SMTP daemon actions if control command */ 738 if (control) 739 { 740 /* Add control socket process */ 741 proc_list_add(CurrentPid, 742 "console socket child", 743 PROC_CONTROL_CHILD, 0, -1, NULL); 744 } 745 else 746 { 747 proc_list_clear(); 748 749 /* clean up background delivery children */ 750 (void) sm_signal(SIGCHLD, reapchild); 751 752 /* Add parent process as first child item */ 753 proc_list_add(CurrentPid, "daemon child", 754 PROC_DAEMON_CHILD, 0, -1, NULL); 755 756 /* don't schedule queue runs if ETRN */ 757 QueueIntvl = 0; 758 #if _FFR_SS_PER_DAEMON 759 if (Daemons[curdaemon].d_supersafe != 760 SAFE_NOTSET) 761 SuperSafe = Daemons[curdaemon].d_supersafe; 762 #endif /* _FFR_SS_PER_DAEMON */ 763 #if _FFR_DM_PER_DAEMON 764 if (Daemons[curdaemon].d_dm != DM_NOTSET) 765 set_delivery_mode( 766 Daemons[curdaemon].d_dm, e); 767 #endif /* _FFR_DM_PER_DAEMON */ 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 #if _FFR_SS_PER_DAEMON 1459 d->d_supersafe = SAFE_NOTSET; 1460 #endif /* _FFR_SS_PER_DAEMON */ 1461 #if _FFR_DM_PER_DAEMON 1462 d->d_dm = DM_NOTSET; 1463 #endif /* _FFR_DM_PER_DAEMON */ 1464 1465 while (p != NULL) 1466 { 1467 register char *f; 1468 register char *v; 1469 1470 while (isascii(*p) && isspace(*p)) 1471 p++; 1472 if (*p == '\0') 1473 break; 1474 f = p; 1475 p = strchr(p, ','); 1476 if (p != NULL) 1477 *p++ = '\0'; 1478 v = strchr(f, '='); 1479 if (v == NULL) 1480 continue; 1481 while (isascii(*++v) && isspace(*v)) 1482 continue; 1483 if (isascii(*f) && islower(*f)) 1484 *f = toupper(*f); 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 = true; 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 for (;;) 2494 { 2495 if (tTd(16, 1)) 2496 sm_dprintf("makeconnection (%s [%s].%d (%d))\n", 2497 host, anynet_ntoa(&addr), ntohs(port), 2498 (int) addr.sa.sa_family); 2499 2500 /* save for logging */ 2501 CurHostAddr = addr; 2502 2503 #if HASRRESVPORT 2504 if (bitnset(M_SECURE_PORT, mci->mci_mailer->m_flags)) 2505 { 2506 int rport = IPPORT_RESERVED - 1; 2507 2508 s = rresvport(&rport); 2509 } 2510 else 2511 #endif /* HASRRESVPORT */ 2512 { 2513 s = socket(addr.sa.sa_family, SOCK_STREAM, 0); 2514 } 2515 if (s < 0) 2516 { 2517 save_errno = errno; 2518 syserr("makeconnection: cannot create socket"); 2519 #if XLA 2520 xla_host_end(host); 2521 #endif /* XLA */ 2522 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2523 #if NETINET6 2524 if (hp != NULL) 2525 freehostent(hp); 2526 #endif /* NETINET6 */ 2527 errno = save_errno; 2528 return EX_TEMPFAIL; 2529 } 2530 2531 #ifdef SO_SNDBUF 2532 if (ClientSettings[family].d_tcpsndbufsize > 0) 2533 { 2534 if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, 2535 (char *) &ClientSettings[family].d_tcpsndbufsize, 2536 sizeof(ClientSettings[family].d_tcpsndbufsize)) < 0) 2537 syserr("makeconnection: setsockopt(SO_SNDBUF)"); 2538 } 2539 #endif /* SO_SNDBUF */ 2540 #ifdef SO_RCVBUF 2541 if (ClientSettings[family].d_tcprcvbufsize > 0) 2542 { 2543 if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, 2544 (char *) &ClientSettings[family].d_tcprcvbufsize, 2545 sizeof(ClientSettings[family].d_tcprcvbufsize)) < 0) 2546 syserr("makeconnection: setsockopt(SO_RCVBUF)"); 2547 } 2548 #endif /* SO_RCVBUF */ 2549 2550 if (tTd(16, 1)) 2551 sm_dprintf("makeconnection: fd=%d\n", s); 2552 2553 /* turn on network debugging? */ 2554 if (tTd(16, 101)) 2555 { 2556 int on = 1; 2557 2558 (void) setsockopt(s, SOL_SOCKET, SO_DEBUG, 2559 (char *)&on, sizeof on); 2560 } 2561 if (e->e_xfp != NULL) /* for debugging */ 2562 (void) sm_io_flush(e->e_xfp, SM_TIME_DEFAULT); 2563 errno = 0; /* for debugging */ 2564 2565 if (clt_bind) 2566 { 2567 int on = 1; 2568 2569 switch (clt_addr.sa.sa_family) 2570 { 2571 #if NETINET 2572 case AF_INET: 2573 if (clt_addr.sin.sin_port != 0) 2574 (void) setsockopt(s, SOL_SOCKET, 2575 SO_REUSEADDR, 2576 (char *) &on, 2577 sizeof on); 2578 break; 2579 #endif /* NETINET */ 2580 2581 #if NETINET6 2582 case AF_INET6: 2583 if (clt_addr.sin6.sin6_port != 0) 2584 (void) setsockopt(s, SOL_SOCKET, 2585 SO_REUSEADDR, 2586 (char *) &on, 2587 sizeof on); 2588 break; 2589 #endif /* NETINET6 */ 2590 } 2591 2592 if (bind(s, &clt_addr.sa, socksize) < 0) 2593 { 2594 save_errno = errno; 2595 (void) close(s); 2596 errno = save_errno; 2597 syserr("makeconnection: cannot bind socket [%s]", 2598 anynet_ntoa(&clt_addr)); 2599 #if NETINET6 2600 if (hp != NULL) 2601 freehostent(hp); 2602 #endif /* NETINET6 */ 2603 errno = save_errno; 2604 return EX_TEMPFAIL; 2605 } 2606 } 2607 2608 /* 2609 ** Linux seems to hang in connect for 90 minutes (!!!). 2610 ** Time out the connect to avoid this problem. 2611 */ 2612 2613 if (setjmp(CtxConnectTimeout) == 0) 2614 { 2615 int i; 2616 2617 if (e->e_ntries <= 0 && TimeOuts.to_iconnect != 0) 2618 ev = sm_setevent(TimeOuts.to_iconnect, 2619 connecttimeout, 0); 2620 else if (TimeOuts.to_connect != 0) 2621 ev = sm_setevent(TimeOuts.to_connect, 2622 connecttimeout, 0); 2623 else 2624 ev = NULL; 2625 2626 switch (ConnectOnlyTo.sa.sa_family) 2627 { 2628 #if NETINET 2629 case AF_INET: 2630 addr.sin.sin_addr.s_addr = ConnectOnlyTo.sin.sin_addr.s_addr; 2631 break; 2632 #endif /* NETINET */ 2633 2634 #if NETINET6 2635 case AF_INET6: 2636 memmove(&addr.sin6.sin6_addr, 2637 &ConnectOnlyTo.sin6.sin6_addr, 2638 IN6ADDRSZ); 2639 break; 2640 #endif /* NETINET6 */ 2641 } 2642 if (tTd(16, 1)) 2643 sm_dprintf("Connecting to [%s]...\n", anynet_ntoa(&addr)); 2644 i = connect(s, (struct sockaddr *) &addr, addrlen); 2645 save_errno = errno; 2646 if (ev != NULL) 2647 sm_clrevent(ev); 2648 if (i >= 0) 2649 break; 2650 } 2651 else 2652 save_errno = errno; 2653 2654 /* couldn't connect.... figure out why */ 2655 (void) close(s); 2656 2657 /* if running demand-dialed connection, try again */ 2658 if (DialDelay > 0 && firstconnect && 2659 bitnset(M_DIALDELAY, mci->mci_mailer->m_flags)) 2660 { 2661 if (tTd(16, 1)) 2662 sm_dprintf("Connect failed (%s); trying again...\n", 2663 sm_errstring(save_errno)); 2664 firstconnect = false; 2665 (void) sleep(DialDelay); 2666 continue; 2667 } 2668 2669 if (LogLevel > 13) 2670 sm_syslog(LOG_INFO, e->e_id, 2671 "makeconnection (%s [%s]) failed: %s", 2672 host, anynet_ntoa(&addr), 2673 sm_errstring(save_errno)); 2674 2675 #if NETINET6 2676 nextaddr: 2677 #endif /* NETINET6 */ 2678 if (hp != NULL && hp->h_addr_list[addrno] != NULL && 2679 (enough == 0 || curtime() < enough)) 2680 { 2681 if (tTd(16, 1)) 2682 sm_dprintf("Connect failed (%s); trying new address....\n", 2683 sm_errstring(save_errno)); 2684 switch (addr.sa.sa_family) 2685 { 2686 #if NETINET 2687 case AF_INET: 2688 memmove(&addr.sin.sin_addr, 2689 hp->h_addr_list[addrno++], 2690 INADDRSZ); 2691 break; 2692 #endif /* NETINET */ 2693 2694 #if NETINET6 2695 case AF_INET6: 2696 memmove(&addr.sin6.sin6_addr, 2697 hp->h_addr_list[addrno++], 2698 IN6ADDRSZ); 2699 break; 2700 #endif /* NETINET6 */ 2701 2702 default: 2703 memmove(addr.sa.sa_data, 2704 hp->h_addr_list[addrno++], 2705 hp->h_length); 2706 break; 2707 } 2708 continue; 2709 } 2710 errno = save_errno; 2711 2712 #if NETINET6 2713 if (family == AF_INET6) 2714 { 2715 if (tTd(16, 1)) 2716 sm_dprintf("Connect failed (%s); retrying with AF_INET....\n", 2717 sm_errstring(save_errno)); 2718 v6found = true; 2719 family = AF_INET; 2720 if (hp != NULL) 2721 { 2722 freehostent(hp); 2723 hp = NULL; 2724 } 2725 goto v4retry; 2726 } 2727 v6tempfail: 2728 #endif /* NETINET6 */ 2729 /* couldn't open connection */ 2730 #if NETINET6 2731 /* Don't clobber an already saved errno from v4retry */ 2732 if (errno > 0) 2733 #endif /* NETINET6 */ 2734 save_errno = errno; 2735 if (tTd(16, 1)) 2736 sm_dprintf("Connect failed (%s)\n", 2737 sm_errstring(save_errno)); 2738 #if XLA 2739 xla_host_end(host); 2740 #endif /* XLA */ 2741 mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); 2742 #if NETINET6 2743 if (hp != NULL) 2744 freehostent(hp); 2745 #endif /* NETINET6 */ 2746 errno = save_errno; 2747 return EX_TEMPFAIL; 2748 } 2749 2750 #if NETINET6 2751 if (hp != NULL) 2752 { 2753 freehostent(hp); 2754 hp = NULL; 2755 } 2756 #endif /* NETINET6 */ 2757 2758 /* connection ok, put it into canonical form */ 2759 mci->mci_out = NULL; 2760 if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 2761 (void *) &s, 2762 SM_IO_WRONLY_B, NULL)) == NULL || 2763 (s = dup(s)) < 0 || 2764 (mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 2765 (void *) &s, 2766 SM_IO_RDONLY_B, NULL)) == NULL) 2767 { 2768 save_errno = errno; 2769 syserr("cannot open SMTP client channel, fd=%d", s); 2770 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2771 if (mci->mci_out != NULL) 2772 (void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT); 2773 (void) close(s); 2774 errno = save_errno; 2775 return EX_TEMPFAIL; 2776 } 2777 sm_io_automode(mci->mci_out, mci->mci_in); 2778 2779 /* set {client_flags} */ 2780 if (ClientSettings[addr.sa.sa_family].d_mflags != NULL) 2781 { 2782 macdefine(&mci->mci_macro, A_PERM, 2783 macid("{client_flags}"), 2784 ClientSettings[addr.sa.sa_family].d_mflags); 2785 } 2786 else 2787 macdefine(&mci->mci_macro, A_PERM, 2788 macid("{client_flags}"), ""); 2789 2790 /* "add" {client_flags} to bitmap */ 2791 if (bitnset(D_IFNHELO, ClientSettings[addr.sa.sa_family].d_flags)) 2792 { 2793 /* look for just this one flag */ 2794 setbitn(D_IFNHELO, d_flags); 2795 } 2796 2797 /* find out name for Interface through which we connect */ 2798 len = sizeof addr; 2799 if (getsockname(s, &addr.sa, &len) == 0) 2800 { 2801 char *name; 2802 char family[5]; 2803 2804 macdefine(&BlankEnvelope.e_macro, A_TEMP, 2805 macid("{if_addr_out}"), anynet_ntoa(&addr)); 2806 (void) sm_snprintf(family, sizeof(family), "%d", 2807 addr.sa.sa_family); 2808 macdefine(&BlankEnvelope.e_macro, A_TEMP, 2809 macid("{if_family_out}"), family); 2810 2811 name = hostnamebyanyaddr(&addr); 2812 macdefine(&BlankEnvelope.e_macro, A_TEMP, 2813 macid("{if_name_out}"), name); 2814 if (LogLevel > 11) 2815 { 2816 /* log connection information */ 2817 sm_syslog(LOG_INFO, e->e_id, 2818 "SMTP outgoing connect on %.40s", name); 2819 } 2820 if (bitnset(D_IFNHELO, d_flags)) 2821 { 2822 if (name[0] != '[' && strchr(name, '.') != NULL) 2823 mci->mci_heloname = newstr(name); 2824 } 2825 } 2826 else 2827 { 2828 macdefine(&BlankEnvelope.e_macro, A_PERM, 2829 macid("{if_name_out}"), NULL); 2830 macdefine(&BlankEnvelope.e_macro, A_PERM, 2831 macid("{if_addr_out}"), NULL); 2832 macdefine(&BlankEnvelope.e_macro, A_PERM, 2833 macid("{if_family_out}"), NULL); 2834 } 2835 2836 #if _FFR_HELONAME 2837 /* Use the configured HeloName as appropriate */ 2838 if (HeloName != NULL && HeloName[0] != '\0') 2839 mci->mci_heloname = newstr(HeloName); 2840 #endif /* _FFR_HELONAME */ 2841 2842 mci_setstat(mci, EX_OK, NULL, NULL); 2843 return EX_OK; 2844 } 2845 2846 static void 2847 connecttimeout(ignore) 2848 int ignore; 2849 { 2850 /* 2851 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 2852 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 2853 ** DOING. 2854 */ 2855 2856 errno = ETIMEDOUT; 2857 longjmp(CtxConnectTimeout, 1); 2858 } 2859 /* 2860 ** MAKECONNECTION_DS -- make a connection to a domain socket. 2861 ** 2862 ** Parameters: 2863 ** mux_path -- the path of the socket to connect to. 2864 ** mci -- a pointer to the mail connection information 2865 ** structure to be filled in. 2866 ** 2867 ** Returns: 2868 ** An exit code telling whether the connection could be 2869 ** made and if not why not. 2870 ** 2871 ** Side Effects: 2872 ** none. 2873 */ 2874 2875 #if NETUNIX 2876 int 2877 makeconnection_ds(mux_path, mci) 2878 char *mux_path; 2879 register MCI *mci; 2880 { 2881 int sock; 2882 int rval, save_errno; 2883 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_ROOTOK|SFF_EXECOK; 2884 struct sockaddr_un unix_addr; 2885 2886 /* if not safe, don't connect */ 2887 rval = safefile(mux_path, RunAsUid, RunAsGid, RunAsUserName, 2888 sff, S_IRUSR|S_IWUSR, NULL); 2889 2890 if (rval != 0) 2891 { 2892 syserr("makeconnection_ds: unsafe domain socket %s", 2893 mux_path); 2894 mci_setstat(mci, EX_TEMPFAIL, "4.3.5", NULL); 2895 errno = rval; 2896 return EX_TEMPFAIL; 2897 } 2898 2899 /* prepare address structure */ 2900 memset(&unix_addr, '\0', sizeof unix_addr); 2901 unix_addr.sun_family = AF_UNIX; 2902 2903 if (strlen(mux_path) >= sizeof unix_addr.sun_path) 2904 { 2905 syserr("makeconnection_ds: domain socket name %s too long", 2906 mux_path); 2907 2908 /* XXX why TEMPFAIL but 5.x.y ? */ 2909 mci_setstat(mci, EX_TEMPFAIL, "5.3.5", NULL); 2910 errno = ENAMETOOLONG; 2911 return EX_UNAVAILABLE; 2912 } 2913 (void) sm_strlcpy(unix_addr.sun_path, mux_path, 2914 sizeof unix_addr.sun_path); 2915 2916 /* initialize domain socket */ 2917 sock = socket(AF_UNIX, SOCK_STREAM, 0); 2918 if (sock == -1) 2919 { 2920 save_errno = errno; 2921 syserr("makeconnection_ds: could not create domain socket %s", 2922 mux_path); 2923 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2924 errno = save_errno; 2925 return EX_TEMPFAIL; 2926 } 2927 2928 /* connect to server */ 2929 if (connect(sock, (struct sockaddr *) &unix_addr, 2930 sizeof(unix_addr)) == -1) 2931 { 2932 save_errno = errno; 2933 syserr("Could not connect to socket %s", mux_path); 2934 mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); 2935 (void) close(sock); 2936 errno = save_errno; 2937 return EX_TEMPFAIL; 2938 } 2939 2940 /* connection ok, put it into canonical form */ 2941 mci->mci_out = NULL; 2942 if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 2943 (void *) &sock, SM_IO_WRONLY_B, NULL)) 2944 == NULL 2945 || (sock = dup(sock)) < 0 || 2946 (mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, 2947 (void *) &sock, SM_IO_RDONLY_B, NULL)) 2948 == NULL) 2949 { 2950 save_errno = errno; 2951 syserr("cannot open SMTP client channel, fd=%d", sock); 2952 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); 2953 if (mci->mci_out != NULL) 2954 (void) sm_io_close(mci->mci_out, SM_TIME_DEFAULT); 2955 (void) close(sock); 2956 errno = save_errno; 2957 return EX_TEMPFAIL; 2958 } 2959 sm_io_automode(mci->mci_out, mci->mci_in); 2960 2961 mci_setstat(mci, EX_OK, NULL, NULL); 2962 errno = 0; 2963 return EX_OK; 2964 } 2965 #endif /* NETUNIX */ 2966 /* 2967 ** SHUTDOWN_DAEMON -- Performs a clean shutdown of the daemon 2968 ** 2969 ** Parameters: 2970 ** none. 2971 ** 2972 ** Returns: 2973 ** none. 2974 ** 2975 ** Side Effects: 2976 ** closes control socket, exits. 2977 */ 2978 2979 void 2980 shutdown_daemon() 2981 { 2982 int i; 2983 char *reason; 2984 2985 sm_allsignals(true); 2986 2987 reason = ShutdownRequest; 2988 ShutdownRequest = NULL; 2989 PendingSignal = 0; 2990 2991 if (LogLevel > 9) 2992 sm_syslog(LOG_INFO, CurEnv->e_id, "stopping daemon, reason=%s", 2993 reason == NULL ? "implicit call" : reason); 2994 2995 FileName = NULL; 2996 closecontrolsocket(true); 2997 #if XLA 2998 xla_all_end(); 2999 #endif /* XLA */ 3000 3001 for (i = 0; i < NDaemons; i++) 3002 { 3003 if (Daemons[i].d_socket >= 0) 3004 { 3005 (void) close(Daemons[i].d_socket); 3006 Daemons[i].d_socket = -1; 3007 3008 #if _FFR_DAEMON_NETUNIX 3009 # if NETUNIX 3010 /* Remove named sockets */ 3011 if (Daemons[i].d_addr.sa.sa_family == AF_UNIX) 3012 { 3013 int rval; 3014 long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_MUSTOWN|SFF_EXECOK|SFF_CREAT; 3015 3016 /* if not safe, don't use it */ 3017 rval = safefile(Daemons[i].d_addr.sunix.sun_path, 3018 RunAsUid, RunAsGid, 3019 RunAsUserName, sff, 3020 S_IRUSR|S_IWUSR, NULL); 3021 if (rval == 0 && 3022 unlink(Daemons[i].d_addr.sunix.sun_path) < 0) 3023 { 3024 sm_syslog(LOG_WARNING, NOQID, 3025 "Could not remove daemon %s socket: %s: %s", 3026 Daemons[i].d_name, 3027 Daemons[i].d_addr.sunix.sun_path, 3028 sm_errstring(errno)); 3029 } 3030 } 3031 # endif /* NETUNIX */ 3032 #endif /* _FFR_DAEMON_NETUNIX */ 3033 } 3034 } 3035 3036 finis(false, true, EX_OK); 3037 } 3038 /* 3039 ** RESTART_DAEMON -- Performs a clean restart of the daemon 3040 ** 3041 ** Parameters: 3042 ** none. 3043 ** 3044 ** Returns: 3045 ** none. 3046 ** 3047 ** Side Effects: 3048 ** restarts the daemon or exits if restart fails. 3049 */ 3050 3051 /* Make a non-DFL/IGN signal a noop */ 3052 #define SM_NOOP_SIGNAL(sig, old) \ 3053 do \ 3054 { \ 3055 (old) = sm_signal((sig), sm_signal_noop); \ 3056 if ((old) == SIG_IGN || (old) == SIG_DFL) \ 3057 (void) sm_signal((sig), (old)); \ 3058 } while (0) 3059 3060 void 3061 restart_daemon() 3062 { 3063 bool drop; 3064 int save_errno; 3065 char *reason; 3066 sigfunc_t ignore, oalrm, ousr1; 3067 extern int DtableSize; 3068 3069 /* clear the events to turn off SIGALRMs */ 3070 sm_clear_events(); 3071 sm_allsignals(true); 3072 3073 reason = RestartRequest; 3074 RestartRequest = NULL; 3075 PendingSignal = 0; 3076 3077 if (SaveArgv[0][0] != '/') 3078 { 3079 if (LogLevel > 3) 3080 sm_syslog(LOG_INFO, NOQID, 3081 "could not restart: need full path"); 3082 finis(false, true, EX_OSFILE); 3083 /* NOTREACHED */ 3084 } 3085 if (LogLevel > 3) 3086 sm_syslog(LOG_INFO, NOQID, "restarting %s due to %s", 3087 SaveArgv[0], 3088 reason == NULL ? "implicit call" : reason); 3089 3090 closecontrolsocket(true); 3091 #if SM_CONF_SHM 3092 cleanup_shm(DaemonPid == getpid()); 3093 #endif /* SM_CONF_SHM */ 3094 3095 /* close locked pid file */ 3096 close_sendmail_pid(); 3097 3098 /* 3099 ** Want to drop to the user who started the process in all cases 3100 ** *but* when running as "smmsp" for the clientmqueue queue run 3101 ** daemon. In that case, UseMSP will be true, RunAsUid should not 3102 ** be root, and RealUid should be either 0 or RunAsUid. 3103 */ 3104 3105 drop = !(UseMSP && RunAsUid != 0 && 3106 (RealUid == 0 || RealUid == RunAsUid)); 3107 3108 if (drop_privileges(drop) != EX_OK) 3109 { 3110 if (LogLevel > 0) 3111 sm_syslog(LOG_ALERT, NOQID, 3112 "could not drop privileges: %s", 3113 sm_errstring(errno)); 3114 finis(false, true, EX_OSERR); 3115 /* NOTREACHED */ 3116 } 3117 3118 sm_close_on_exec(STDERR_FILENO + 1, DtableSize); 3119 3120 /* 3121 ** Need to allow signals before execve() to make them "harmless". 3122 ** However, the default action can be "terminate", so it isn't 3123 ** really harmless. Setting signals to IGN will cause them to be 3124 ** ignored in the new process to, so that isn't a good alternative. 3125 */ 3126 3127 SM_NOOP_SIGNAL(SIGALRM, oalrm); 3128 SM_NOOP_SIGNAL(SIGCHLD, ignore); 3129 SM_NOOP_SIGNAL(SIGHUP, ignore); 3130 SM_NOOP_SIGNAL(SIGINT, ignore); 3131 SM_NOOP_SIGNAL(SIGPIPE, ignore); 3132 SM_NOOP_SIGNAL(SIGTERM, ignore); 3133 #ifdef SIGUSR1 3134 SM_NOOP_SIGNAL(SIGUSR1, ousr1); 3135 #endif /* SIGUSR1 */ 3136 3137 /* Turn back on signals */ 3138 sm_allsignals(false); 3139 3140 (void) execve(SaveArgv[0], (ARGV_T) SaveArgv, (ARGV_T) ExternalEnviron); 3141 save_errno = errno; 3142 3143 /* block signals again and restore needed signals */ 3144 sm_allsignals(true); 3145 3146 /* For finis() events */ 3147 (void) sm_signal(SIGALRM, oalrm); 3148 3149 #ifdef SIGUSR1 3150 /* For debugging finis() */ 3151 (void) sm_signal(SIGUSR1, ousr1); 3152 #endif /* SIGUSR1 */ 3153 3154 errno = save_errno; 3155 if (LogLevel > 0) 3156 sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %s", 3157 SaveArgv[0], sm_errstring(errno)); 3158 finis(false, true, EX_OSFILE); 3159 /* NOTREACHED */ 3160 } 3161 /* 3162 ** MYHOSTNAME -- return the name of this host. 3163 ** 3164 ** Parameters: 3165 ** hostbuf -- a place to return the name of this host. 3166 ** size -- the size of hostbuf. 3167 ** 3168 ** Returns: 3169 ** A list of aliases for this host. 3170 ** 3171 ** Side Effects: 3172 ** Adds numeric codes to $=w. 3173 */ 3174 3175 struct hostent * 3176 myhostname(hostbuf, size) 3177 char hostbuf[]; 3178 int size; 3179 { 3180 register struct hostent *hp; 3181 3182 if (gethostname(hostbuf, size) < 0 || hostbuf[0] == '\0') 3183 (void) sm_strlcpy(hostbuf, "localhost", size); 3184 hp = sm_gethostbyname(hostbuf, InetMode); 3185 #if NETINET && NETINET6 3186 if (hp == NULL && InetMode == AF_INET6) 3187 { 3188 /* 3189 ** It's possible that this IPv6 enabled machine doesn't 3190 ** actually have any IPv6 interfaces and, therefore, no 3191 ** IPv6 addresses. Fall back to AF_INET. 3192 */ 3193 3194 hp = sm_gethostbyname(hostbuf, AF_INET); 3195 } 3196 #endif /* NETINET && NETINET6 */ 3197 if (hp == NULL) 3198 return NULL; 3199 if (strchr(hp->h_name, '.') != NULL || strchr(hostbuf, '.') == NULL) 3200 (void) cleanstrcpy(hostbuf, hp->h_name, size); 3201 3202 #if NETINFO 3203 if (strchr(hostbuf, '.') == NULL) 3204 { 3205 char *domainname; 3206 3207 domainname = ni_propval("/locations", NULL, "resolver", 3208 "domain", '\0'); 3209 if (domainname != NULL && 3210 strlen(domainname) + strlen(hostbuf) + 1 < size) 3211 (void) sm_strlcat2(hostbuf, ".", domainname, size); 3212 } 3213 #endif /* NETINFO */ 3214 3215 /* 3216 ** If there is still no dot in the name, try looking for a 3217 ** dotted alias. 3218 */ 3219 3220 if (strchr(hostbuf, '.') == NULL) 3221 { 3222 char **ha; 3223 3224 for (ha = hp->h_aliases; ha != NULL && *ha != NULL; ha++) 3225 { 3226 if (strchr(*ha, '.') != NULL) 3227 { 3228 (void) cleanstrcpy(hostbuf, *ha, size - 1); 3229 hostbuf[size - 1] = '\0'; 3230 break; 3231 } 3232 } 3233 } 3234 3235 /* 3236 ** If _still_ no dot, wait for a while and try again -- it is 3237 ** possible that some service is starting up. This can result 3238 ** in excessive delays if the system is badly configured, but 3239 ** there really isn't a way around that, particularly given that 3240 ** the config file hasn't been read at this point. 3241 ** All in all, a bit of a mess. 3242 */ 3243 3244 if (strchr(hostbuf, '.') == NULL && 3245 !getcanonname(hostbuf, size, true, NULL)) 3246 { 3247 sm_syslog(LOG_CRIT, NOQID, 3248 "My unqualified host name (%s) unknown; sleeping for retry", 3249 hostbuf); 3250 message("My unqualified host name (%s) unknown; sleeping for retry", 3251 hostbuf); 3252 (void) sleep(60); 3253 if (!getcanonname(hostbuf, size, true, NULL)) 3254 { 3255 sm_syslog(LOG_ALERT, NOQID, 3256 "unable to qualify my own domain name (%s) -- using short name", 3257 hostbuf); 3258 message("WARNING: unable to qualify my own domain name (%s) -- using short name", 3259 hostbuf); 3260 } 3261 } 3262 return hp; 3263 } 3264 /* 3265 ** ADDRCMP -- compare two host addresses 3266 ** 3267 ** Parameters: 3268 ** hp -- hostent structure for the first address 3269 ** ha -- actual first address 3270 ** sa -- second address 3271 ** 3272 ** Returns: 3273 ** 0 -- if ha and sa match 3274 ** else -- they don't match 3275 */ 3276 3277 static int 3278 addrcmp(hp, ha, sa) 3279 struct hostent *hp; 3280 char *ha; 3281 SOCKADDR *sa; 3282 { 3283 #if NETINET6 3284 unsigned char *a; 3285 #endif /* NETINET6 */ 3286 3287 switch (sa->sa.sa_family) 3288 { 3289 #if NETINET 3290 case AF_INET: 3291 if (hp->h_addrtype == AF_INET) 3292 return memcmp(ha, (char *) &sa->sin.sin_addr, INADDRSZ); 3293 break; 3294 #endif /* NETINET */ 3295 3296 #if NETINET6 3297 case AF_INET6: 3298 a = (unsigned char *) &sa->sin6.sin6_addr; 3299 3300 /* Straight binary comparison */ 3301 if (hp->h_addrtype == AF_INET6) 3302 return memcmp(ha, a, IN6ADDRSZ); 3303 3304 /* If IPv4-mapped IPv6 address, compare the IPv4 section */ 3305 if (hp->h_addrtype == AF_INET && 3306 IN6_IS_ADDR_V4MAPPED(&sa->sin6.sin6_addr)) 3307 return memcmp(a + IN6ADDRSZ - INADDRSZ, ha, INADDRSZ); 3308 break; 3309 #endif /* NETINET6 */ 3310 } 3311 return -1; 3312 } 3313 /* 3314 ** GETAUTHINFO -- get the real host name associated with a file descriptor 3315 ** 3316 ** Uses RFC1413 protocol to try to get info from the other end. 3317 ** 3318 ** Parameters: 3319 ** fd -- the descriptor 3320 ** may_be_forged -- an outage that is set to true if the 3321 ** forward lookup of RealHostName does not match 3322 ** RealHostAddr; set to false if they do match. 3323 ** 3324 ** Returns: 3325 ** The user@host information associated with this descriptor. 3326 */ 3327 3328 static jmp_buf CtxAuthTimeout; 3329 3330 static void 3331 authtimeout(ignore) 3332 int ignore; 3333 { 3334 /* 3335 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 3336 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 3337 ** DOING. 3338 */ 3339 3340 errno = ETIMEDOUT; 3341 longjmp(CtxAuthTimeout, 1); 3342 } 3343 3344 char * 3345 getauthinfo(fd, may_be_forged) 3346 int fd; 3347 bool *may_be_forged; 3348 { 3349 unsigned short SM_NONVOLATILE port = 0; 3350 SOCKADDR_LEN_T falen; 3351 register char *volatile p = NULL; 3352 SOCKADDR la; 3353 SOCKADDR_LEN_T lalen; 3354 #ifndef NO_GETSERVBYNAME 3355 register struct servent *sp; 3356 # if NETINET 3357 static unsigned short port4 = 0; 3358 # endif /* NETINET */ 3359 # if NETINET6 3360 static unsigned short port6 = 0; 3361 # endif /* NETINET6 */ 3362 #endif /* ! NO_GETSERVBYNAME */ 3363 volatile int s; 3364 int i = 0; 3365 size_t len; 3366 SM_EVENT *ev; 3367 int nleft; 3368 struct hostent *hp; 3369 char *ostype = NULL; 3370 char **ha; 3371 char ibuf[MAXNAME + 1]; 3372 static char hbuf[MAXNAME + MAXAUTHINFO + 11]; 3373 3374 *may_be_forged = false; 3375 falen = sizeof RealHostAddr; 3376 if (isatty(fd) || (i = getpeername(fd, &RealHostAddr.sa, &falen)) < 0 || 3377 falen <= 0 || RealHostAddr.sa.sa_family == 0) 3378 { 3379 if (i < 0) 3380 { 3381 /* 3382 ** ENOTSOCK is OK: bail on anything else, but reset 3383 ** errno in this case, so a mis-report doesn't 3384 ** happen later. 3385 */ 3386 3387 if (errno != ENOTSOCK) 3388 return NULL; 3389 errno = 0; 3390 } 3391 (void) sm_strlcpyn(hbuf, sizeof hbuf, 2, RealUserName, 3392 "@localhost"); 3393 if (tTd(9, 1)) 3394 sm_dprintf("getauthinfo: %s\n", hbuf); 3395 return hbuf; 3396 } 3397 3398 if (RealHostName == NULL) 3399 { 3400 /* translate that to a host name */ 3401 RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr)); 3402 if (strlen(RealHostName) > MAXNAME) 3403 RealHostName[MAXNAME] = '\0'; /* XXX - 1 ? */ 3404 } 3405 3406 /* cross check RealHostName with forward DNS lookup */ 3407 if (anynet_ntoa(&RealHostAddr)[0] != '[' && 3408 RealHostName[0] != '[') 3409 { 3410 int family; 3411 3412 family = RealHostAddr.sa.sa_family; 3413 #if NETINET6 && NEEDSGETIPNODE 3414 /* 3415 ** If RealHostAddr is an IPv6 connection with an 3416 ** IPv4-mapped address, we need RealHostName's IPv4 3417 ** address(es) for addrcmp() to compare against 3418 ** RealHostAddr. 3419 ** 3420 ** Actually, we only need to do this for systems 3421 ** which NEEDSGETIPNODE since the real getipnodebyname() 3422 ** already does V4MAPPED address via the AI_V4MAPPEDCFG 3423 ** flag. A better fix to this problem is to add this 3424 ** functionality to our stub getipnodebyname(). 3425 */ 3426 3427 if (family == AF_INET6 && 3428 IN6_IS_ADDR_V4MAPPED(&RealHostAddr.sin6.sin6_addr)) 3429 family = AF_INET; 3430 #endif /* NETINET6 && NEEDSGETIPNODE */ 3431 3432 /* try to match the reverse against the forward lookup */ 3433 hp = sm_gethostbyname(RealHostName, family); 3434 if (hp == NULL) 3435 { 3436 /* XXX: Could be a temporary error on forward lookup */ 3437 *may_be_forged = true; 3438 } 3439 else 3440 { 3441 for (ha = hp->h_addr_list; *ha != NULL; ha++) 3442 { 3443 if (addrcmp(hp, *ha, &RealHostAddr) == 0) 3444 break; 3445 } 3446 *may_be_forged = *ha == NULL; 3447 #if NETINET6 3448 freehostent(hp); 3449 hp = NULL; 3450 #endif /* NETINET6 */ 3451 } 3452 } 3453 3454 if (TimeOuts.to_ident == 0) 3455 goto noident; 3456 3457 lalen = sizeof la; 3458 switch (RealHostAddr.sa.sa_family) 3459 { 3460 #if NETINET 3461 case AF_INET: 3462 if (getsockname(fd, &la.sa, &lalen) < 0 || 3463 lalen <= 0 || 3464 la.sa.sa_family != AF_INET) 3465 { 3466 /* no ident info */ 3467 goto noident; 3468 } 3469 port = RealHostAddr.sin.sin_port; 3470 3471 /* create ident query */ 3472 (void) sm_snprintf(ibuf, sizeof ibuf, "%d,%d\r\n", 3473 ntohs(RealHostAddr.sin.sin_port), 3474 ntohs(la.sin.sin_port)); 3475 3476 /* create local address */ 3477 la.sin.sin_port = 0; 3478 3479 /* create foreign address */ 3480 # ifdef NO_GETSERVBYNAME 3481 RealHostAddr.sin.sin_port = htons(113); 3482 # else /* NO_GETSERVBYNAME */ 3483 3484 /* 3485 ** getservbyname() consumes about 5% of the time 3486 ** when receiving a small message (almost all of the time 3487 ** spent in this routine). 3488 ** Hence we store the port in a static variable 3489 ** to save this time. 3490 ** The portnumber shouldn't change very often... 3491 ** This code makes the assumption that the port number 3492 ** is not 0. 3493 */ 3494 3495 if (port4 == 0) 3496 { 3497 sp = getservbyname("auth", "tcp"); 3498 if (sp != NULL) 3499 port4 = sp->s_port; 3500 else 3501 port4 = htons(113); 3502 } 3503 RealHostAddr.sin.sin_port = port4; 3504 break; 3505 # endif /* NO_GETSERVBYNAME */ 3506 #endif /* NETINET */ 3507 3508 #if NETINET6 3509 case AF_INET6: 3510 if (getsockname(fd, &la.sa, &lalen) < 0 || 3511 lalen <= 0 || 3512 la.sa.sa_family != AF_INET6) 3513 { 3514 /* no ident info */ 3515 goto noident; 3516 } 3517 port = RealHostAddr.sin6.sin6_port; 3518 3519 /* create ident query */ 3520 (void) sm_snprintf(ibuf, sizeof ibuf, "%d,%d\r\n", 3521 ntohs(RealHostAddr.sin6.sin6_port), 3522 ntohs(la.sin6.sin6_port)); 3523 3524 /* create local address */ 3525 la.sin6.sin6_port = 0; 3526 3527 /* create foreign address */ 3528 # ifdef NO_GETSERVBYNAME 3529 RealHostAddr.sin6.sin6_port = htons(113); 3530 # else /* NO_GETSERVBYNAME */ 3531 if (port6 == 0) 3532 { 3533 sp = getservbyname("auth", "tcp"); 3534 if (sp != NULL) 3535 port6 = sp->s_port; 3536 else 3537 port6 = htons(113); 3538 } 3539 RealHostAddr.sin6.sin6_port = port6; 3540 break; 3541 # endif /* NO_GETSERVBYNAME */ 3542 #endif /* NETINET6 */ 3543 default: 3544 /* no ident info */ 3545 goto noident; 3546 } 3547 3548 s = -1; 3549 if (setjmp(CtxAuthTimeout) != 0) 3550 { 3551 if (s >= 0) 3552 (void) close(s); 3553 goto noident; 3554 } 3555 3556 /* put a timeout around the whole thing */ 3557 ev = sm_setevent(TimeOuts.to_ident, authtimeout, 0); 3558 3559 /* connect to foreign IDENT server using same address as SMTP socket */ 3560 s = socket(la.sa.sa_family, SOCK_STREAM, 0); 3561 if (s < 0) 3562 { 3563 sm_clrevent(ev); 3564 goto noident; 3565 } 3566 if (bind(s, &la.sa, lalen) < 0 || 3567 connect(s, &RealHostAddr.sa, lalen) < 0) 3568 goto closeident; 3569 3570 if (tTd(9, 10)) 3571 sm_dprintf("getauthinfo: sent %s", ibuf); 3572 3573 /* send query */ 3574 if (write(s, ibuf, strlen(ibuf)) < 0) 3575 goto closeident; 3576 3577 /* get result */ 3578 p = &ibuf[0]; 3579 nleft = sizeof ibuf - 1; 3580 while ((i = read(s, p, nleft)) > 0) 3581 { 3582 char *s; 3583 3584 p += i; 3585 nleft -= i; 3586 *p = '\0'; 3587 if ((s = strchr(ibuf, '\n')) != NULL) 3588 { 3589 if (p > s + 1) 3590 { 3591 p = s + 1; 3592 *p = '\0'; 3593 } 3594 break; 3595 } 3596 if (nleft <= 0) 3597 break; 3598 } 3599 (void) close(s); 3600 sm_clrevent(ev); 3601 if (i < 0 || p == &ibuf[0]) 3602 goto noident; 3603 3604 if (p >= &ibuf[2] && *--p == '\n' && *--p == '\r') 3605 p--; 3606 *++p = '\0'; 3607 3608 if (tTd(9, 3)) 3609 sm_dprintf("getauthinfo: got %s\n", ibuf); 3610 3611 /* parse result */ 3612 p = strchr(ibuf, ':'); 3613 if (p == NULL) 3614 { 3615 /* malformed response */ 3616 goto noident; 3617 } 3618 while (isascii(*++p) && isspace(*p)) 3619 continue; 3620 if (sm_strncasecmp(p, "userid", 6) != 0) 3621 { 3622 /* presumably an error string */ 3623 goto noident; 3624 } 3625 p += 6; 3626 while (isascii(*p) && isspace(*p)) 3627 p++; 3628 if (*p++ != ':') 3629 { 3630 /* either useridxx or malformed response */ 3631 goto noident; 3632 } 3633 3634 /* p now points to the OSTYPE field */ 3635 while (isascii(*p) && isspace(*p)) 3636 p++; 3637 ostype = p; 3638 p = strchr(p, ':'); 3639 if (p == NULL) 3640 { 3641 /* malformed response */ 3642 goto noident; 3643 } 3644 else 3645 { 3646 char *charset; 3647 3648 *p = '\0'; 3649 charset = strchr(ostype, ','); 3650 if (charset != NULL) 3651 *charset = '\0'; 3652 } 3653 3654 /* 1413 says don't do this -- but it's broken otherwise */ 3655 while (isascii(*++p) && isspace(*p)) 3656 continue; 3657 3658 /* p now points to the authenticated name -- copy carefully */ 3659 if (sm_strncasecmp(ostype, "other", 5) == 0 && 3660 (ostype[5] == ' ' || ostype[5] == '\0')) 3661 { 3662 (void) sm_strlcpy(hbuf, "IDENT:", sizeof hbuf); 3663 cleanstrcpy(&hbuf[6], p, MAXAUTHINFO); 3664 } 3665 else 3666 cleanstrcpy(hbuf, p, MAXAUTHINFO); 3667 len = strlen(hbuf); 3668 (void) sm_strlcpyn(&hbuf[len], sizeof hbuf - len, 2, "@", 3669 RealHostName == NULL ? "localhost" : RealHostName); 3670 goto postident; 3671 3672 closeident: 3673 (void) close(s); 3674 sm_clrevent(ev); 3675 3676 noident: 3677 /* put back the original incoming port */ 3678 switch (RealHostAddr.sa.sa_family) 3679 { 3680 #if NETINET 3681 case AF_INET: 3682 if (port > 0) 3683 RealHostAddr.sin.sin_port = port; 3684 break; 3685 #endif /* NETINET */ 3686 3687 #if NETINET6 3688 case AF_INET6: 3689 if (port > 0) 3690 RealHostAddr.sin6.sin6_port = port; 3691 break; 3692 #endif /* NETINET6 */ 3693 } 3694 3695 if (RealHostName == NULL) 3696 { 3697 if (tTd(9, 1)) 3698 sm_dprintf("getauthinfo: NULL\n"); 3699 return NULL; 3700 } 3701 (void) sm_strlcpy(hbuf, RealHostName, sizeof hbuf); 3702 3703 postident: 3704 #if IP_SRCROUTE 3705 # ifndef GET_IPOPT_DST 3706 # define GET_IPOPT_DST(dst) (dst) 3707 # endif /* ! GET_IPOPT_DST */ 3708 /* 3709 ** Extract IP source routing information. 3710 ** 3711 ** Format of output for a connection from site a through b 3712 ** through c to d: 3713 ** loose: @site-c@site-b:site-a 3714 ** strict: !@site-c@site-b:site-a 3715 ** 3716 ** o - pointer within ipopt_list structure. 3717 ** q - pointer within ls/ss rr route data 3718 ** p - pointer to hbuf 3719 */ 3720 3721 if (RealHostAddr.sa.sa_family == AF_INET) 3722 { 3723 SOCKOPT_LEN_T ipoptlen; 3724 int j; 3725 unsigned char *q; 3726 unsigned char *o; 3727 int l; 3728 struct IPOPTION ipopt; 3729 3730 ipoptlen = sizeof ipopt; 3731 if (getsockopt(fd, IPPROTO_IP, IP_OPTIONS, 3732 (char *) &ipopt, &ipoptlen) < 0) 3733 goto noipsr; 3734 if (ipoptlen == 0) 3735 goto noipsr; 3736 o = (unsigned char *) ipopt.IP_LIST; 3737 while (o != NULL && o < (unsigned char *) &ipopt + ipoptlen) 3738 { 3739 switch (*o) 3740 { 3741 case IPOPT_EOL: 3742 o = NULL; 3743 break; 3744 3745 case IPOPT_NOP: 3746 o++; 3747 break; 3748 3749 case IPOPT_SSRR: 3750 case IPOPT_LSRR: 3751 /* 3752 ** Source routing. 3753 ** o[0] is the option type (loose/strict). 3754 ** o[1] is the length of this option, 3755 ** including option type and 3756 ** length. 3757 ** o[2] is the pointer into the route 3758 ** data. 3759 ** o[3] begins the route data. 3760 */ 3761 3762 p = &hbuf[strlen(hbuf)]; 3763 l = sizeof hbuf - (hbuf - p) - 6; 3764 (void) sm_snprintf(p, SPACELEFT(hbuf, p), 3765 " [%s@%.*s", 3766 *o == IPOPT_SSRR ? "!" : "", 3767 l > 240 ? 120 : l / 2, 3768 inet_ntoa(GET_IPOPT_DST(ipopt.IP_DST))); 3769 i = strlen(p); 3770 p += i; 3771 l -= strlen(p); 3772 3773 j = o[1] / sizeof(struct in_addr) - 1; 3774 3775 /* q skips length and router pointer to data */ 3776 q = &o[3]; 3777 for ( ; j >= 0; j--) 3778 { 3779 struct in_addr addr; 3780 3781 memcpy(&addr, q, sizeof(addr)); 3782 (void) sm_snprintf(p, 3783 SPACELEFT(hbuf, p), 3784 "%c%.*s", 3785 j != 0 ? '@' : ':', 3786 l > 240 ? 120 : 3787 j == 0 ? l : l / 2, 3788 inet_ntoa(addr)); 3789 i = strlen(p); 3790 p += i; 3791 l -= i + 1; 3792 q += sizeof(struct in_addr); 3793 } 3794 o += o[1]; 3795 break; 3796 3797 default: 3798 /* Skip over option */ 3799 o += o[1]; 3800 break; 3801 } 3802 } 3803 (void) sm_snprintf(p, SPACELEFT(hbuf, p), "]"); 3804 goto postipsr; 3805 } 3806 3807 noipsr: 3808 #endif /* IP_SRCROUTE */ 3809 if (RealHostName != NULL && RealHostName[0] != '[') 3810 { 3811 p = &hbuf[strlen(hbuf)]; 3812 (void) sm_snprintf(p, SPACELEFT(hbuf, p), " [%.100s]", 3813 anynet_ntoa(&RealHostAddr)); 3814 } 3815 if (*may_be_forged) 3816 { 3817 p = &hbuf[strlen(hbuf)]; 3818 (void) sm_strlcpy(p, " (may be forged)", SPACELEFT(hbuf, p)); 3819 macdefine(&BlankEnvelope.e_macro, A_PERM, 3820 macid("{client_resolve}"), "FORGED"); 3821 } 3822 3823 #if IP_SRCROUTE 3824 postipsr: 3825 #endif /* IP_SRCROUTE */ 3826 3827 /* put back the original incoming port */ 3828 switch (RealHostAddr.sa.sa_family) 3829 { 3830 #if NETINET 3831 case AF_INET: 3832 if (port > 0) 3833 RealHostAddr.sin.sin_port = port; 3834 break; 3835 #endif /* NETINET */ 3836 3837 #if NETINET6 3838 case AF_INET6: 3839 if (port > 0) 3840 RealHostAddr.sin6.sin6_port = port; 3841 break; 3842 #endif /* NETINET6 */ 3843 } 3844 3845 if (tTd(9, 1)) 3846 sm_dprintf("getauthinfo: %s\n", hbuf); 3847 return hbuf; 3848 } 3849 /* 3850 ** HOST_MAP_LOOKUP -- turn a hostname into canonical form 3851 ** 3852 ** Parameters: 3853 ** map -- a pointer to this map. 3854 ** name -- the (presumably unqualified) hostname. 3855 ** av -- unused -- for compatibility with other mapping 3856 ** functions. 3857 ** statp -- an exit status (out parameter) -- set to 3858 ** EX_TEMPFAIL if the name server is unavailable. 3859 ** 3860 ** Returns: 3861 ** The mapping, if found. 3862 ** NULL if no mapping found. 3863 ** 3864 ** Side Effects: 3865 ** Looks up the host specified in hbuf. If it is not 3866 ** the canonical name for that host, return the canonical 3867 ** name (unless MF_MATCHONLY is set, which will cause the 3868 ** status only to be returned). 3869 */ 3870 3871 char * 3872 host_map_lookup(map, name, av, statp) 3873 MAP *map; 3874 char *name; 3875 char **av; 3876 int *statp; 3877 { 3878 register struct hostent *hp; 3879 #if NETINET 3880 struct in_addr in_addr; 3881 #endif /* NETINET */ 3882 #if NETINET6 3883 struct in6_addr in6_addr; 3884 #endif /* NETINET6 */ 3885 char *cp, *ans = NULL; 3886 register STAB *s; 3887 time_t now; 3888 #if NAMED_BIND 3889 time_t SM_NONVOLATILE retrans = 0; 3890 int SM_NONVOLATILE retry = 0; 3891 #endif /* NAMED_BIND */ 3892 char hbuf[MAXNAME + 1]; 3893 3894 /* 3895 ** See if we have already looked up this name. If so, just 3896 ** return it (unless expired). 3897 */ 3898 3899 now = curtime(); 3900 s = stab(name, ST_NAMECANON, ST_ENTER); 3901 if (bitset(NCF_VALID, s->s_namecanon.nc_flags) && 3902 s->s_namecanon.nc_exp >= now) 3903 { 3904 if (tTd(9, 1)) 3905 sm_dprintf("host_map_lookup(%s) => CACHE %s\n", 3906 name, 3907 s->s_namecanon.nc_cname == NULL 3908 ? "NULL" 3909 : s->s_namecanon.nc_cname); 3910 errno = s->s_namecanon.nc_errno; 3911 SM_SET_H_ERRNO(s->s_namecanon.nc_herrno); 3912 *statp = s->s_namecanon.nc_stat; 3913 if (*statp == EX_TEMPFAIL) 3914 { 3915 CurEnv->e_status = "4.4.3"; 3916 message("851 %s: Name server timeout", 3917 shortenstring(name, 33)); 3918 } 3919 if (*statp != EX_OK) 3920 return NULL; 3921 if (s->s_namecanon.nc_cname == NULL) 3922 { 3923 syserr("host_map_lookup(%s): bogus NULL cache entry, errno=%d, h_errno=%d", 3924 name, 3925 s->s_namecanon.nc_errno, 3926 s->s_namecanon.nc_herrno); 3927 return NULL; 3928 } 3929 if (bitset(MF_MATCHONLY, map->map_mflags)) 3930 cp = map_rewrite(map, name, strlen(name), NULL); 3931 else 3932 cp = map_rewrite(map, 3933 s->s_namecanon.nc_cname, 3934 strlen(s->s_namecanon.nc_cname), 3935 av); 3936 return cp; 3937 } 3938 3939 /* 3940 ** If we are running without a regular network connection (usually 3941 ** dial-on-demand) and we are just queueing, we want to avoid DNS 3942 ** lookups because those could try to connect to a server. 3943 */ 3944 3945 if (CurEnv->e_sendmode == SM_DEFER && 3946 bitset(MF_DEFER, map->map_mflags)) 3947 { 3948 if (tTd(9, 1)) 3949 sm_dprintf("host_map_lookup(%s) => DEFERRED\n", name); 3950 *statp = EX_TEMPFAIL; 3951 return NULL; 3952 } 3953 3954 /* 3955 ** If first character is a bracket, then it is an address 3956 ** lookup. Address is copied into a temporary buffer to 3957 ** strip the brackets and to preserve name if address is 3958 ** unknown. 3959 */ 3960 3961 if (tTd(9, 1)) 3962 sm_dprintf("host_map_lookup(%s) => ", name); 3963 #if NAMED_BIND 3964 if (map->map_timeout > 0) 3965 { 3966 retrans = _res.retrans; 3967 _res.retrans = map->map_timeout; 3968 } 3969 if (map->map_retry > 0) 3970 { 3971 retry = _res.retry; 3972 _res.retry = map->map_retry; 3973 } 3974 #endif /* NAMED_BIND */ 3975 3976 /* set default TTL */ 3977 s->s_namecanon.nc_exp = now + SM_DEFAULT_TTL; 3978 if (*name != '[') 3979 { 3980 int ttl; 3981 3982 (void) sm_strlcpy(hbuf, name, sizeof hbuf); 3983 if (getcanonname(hbuf, sizeof hbuf - 1, !HasWildcardMX, &ttl)) 3984 { 3985 ans = hbuf; 3986 if (ttl > 0) 3987 s->s_namecanon.nc_exp = now + SM_MIN(ttl, 3988 SM_DEFAULT_TTL); 3989 } 3990 } 3991 else 3992 { 3993 if ((cp = strchr(name, ']')) == NULL) 3994 { 3995 if (tTd(9, 1)) 3996 sm_dprintf("FAILED\n"); 3997 return NULL; 3998 } 3999 *cp = '\0'; 4000 4001 hp = NULL; 4002 #if NETINET 4003 if ((in_addr.s_addr = inet_addr(&name[1])) != INADDR_NONE) 4004 hp = sm_gethostbyaddr((char *)&in_addr, 4005 INADDRSZ, AF_INET); 4006 #endif /* NETINET */ 4007 #if NETINET6 4008 if (hp == NULL && 4009 anynet_pton(AF_INET6, &name[1], &in6_addr) == 1) 4010 hp = sm_gethostbyaddr((char *)&in6_addr, 4011 IN6ADDRSZ, AF_INET6); 4012 #endif /* NETINET6 */ 4013 *cp = ']'; 4014 4015 if (hp != NULL) 4016 { 4017 /* found a match -- copy out */ 4018 ans = denlstring((char *) hp->h_name, true, true); 4019 #if NETINET6 4020 if (ans == hp->h_name) 4021 { 4022 static char n[MAXNAME + 1]; 4023 4024 /* hp->h_name is about to disappear */ 4025 (void) sm_strlcpy(n, ans, sizeof n); 4026 ans = n; 4027 } 4028 freehostent(hp); 4029 hp = NULL; 4030 #endif /* NETINET6 */ 4031 } 4032 } 4033 #if NAMED_BIND 4034 if (map->map_timeout > 0) 4035 _res.retrans = retrans; 4036 if (map->map_retry > 0) 4037 _res.retry = retry; 4038 #endif /* NAMED_BIND */ 4039 4040 s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */ 4041 4042 /* Found an answer */ 4043 if (ans != NULL) 4044 { 4045 s->s_namecanon.nc_stat = *statp = EX_OK; 4046 if (s->s_namecanon.nc_cname != NULL) 4047 sm_free(s->s_namecanon.nc_cname); 4048 s->s_namecanon.nc_cname = sm_strdup_x(ans); 4049 if (bitset(MF_MATCHONLY, map->map_mflags)) 4050 cp = map_rewrite(map, name, strlen(name), NULL); 4051 else 4052 cp = map_rewrite(map, ans, strlen(ans), av); 4053 if (tTd(9, 1)) 4054 sm_dprintf("FOUND %s\n", ans); 4055 return cp; 4056 } 4057 4058 4059 /* No match found */ 4060 s->s_namecanon.nc_errno = errno; 4061 #if NAMED_BIND 4062 s->s_namecanon.nc_herrno = h_errno; 4063 if (tTd(9, 1)) 4064 sm_dprintf("FAIL (%d)\n", h_errno); 4065 switch (h_errno) 4066 { 4067 case TRY_AGAIN: 4068 if (UseNameServer) 4069 { 4070 CurEnv->e_status = "4.4.3"; 4071 message("851 %s: Name server timeout", 4072 shortenstring(name, 33)); 4073 } 4074 *statp = EX_TEMPFAIL; 4075 break; 4076 4077 case HOST_NOT_FOUND: 4078 case NO_DATA: 4079 *statp = EX_NOHOST; 4080 break; 4081 4082 case NO_RECOVERY: 4083 *statp = EX_SOFTWARE; 4084 break; 4085 4086 default: 4087 *statp = EX_UNAVAILABLE; 4088 break; 4089 } 4090 #else /* NAMED_BIND */ 4091 if (tTd(9, 1)) 4092 sm_dprintf("FAIL\n"); 4093 *statp = EX_NOHOST; 4094 #endif /* NAMED_BIND */ 4095 s->s_namecanon.nc_stat = *statp; 4096 return NULL; 4097 } 4098 /* 4099 ** HOST_MAP_INIT -- initialize host class structures 4100 ** 4101 ** Parameters: 4102 ** map -- a pointer to this map. 4103 ** args -- argument string. 4104 ** 4105 ** Returns: 4106 ** true. 4107 */ 4108 4109 bool 4110 host_map_init(map, args) 4111 MAP *map; 4112 char *args; 4113 { 4114 register char *p = args; 4115 4116 for (;;) 4117 { 4118 while (isascii(*p) && isspace(*p)) 4119 p++; 4120 if (*p != '-') 4121 break; 4122 switch (*++p) 4123 { 4124 case 'a': 4125 map->map_app = ++p; 4126 break; 4127 4128 case 'T': 4129 map->map_tapp = ++p; 4130 break; 4131 4132 case 'm': 4133 map->map_mflags |= MF_MATCHONLY; 4134 break; 4135 4136 case 't': 4137 map->map_mflags |= MF_NODEFER; 4138 break; 4139 4140 case 'S': /* only for consistency */ 4141 map->map_spacesub = *++p; 4142 break; 4143 4144 case 'D': 4145 map->map_mflags |= MF_DEFER; 4146 break; 4147 4148 case 'd': 4149 { 4150 char *h; 4151 4152 while (isascii(*++p) && isspace(*p)) 4153 continue; 4154 h = strchr(p, ' '); 4155 if (h != NULL) 4156 *h = '\0'; 4157 map->map_timeout = convtime(p, 's'); 4158 if (h != NULL) 4159 *h = ' '; 4160 } 4161 break; 4162 4163 case 'r': 4164 while (isascii(*++p) && isspace(*p)) 4165 continue; 4166 map->map_retry = atoi(p); 4167 break; 4168 } 4169 while (*p != '\0' && !(isascii(*p) && isspace(*p))) 4170 p++; 4171 if (*p != '\0') 4172 *p++ = '\0'; 4173 } 4174 if (map->map_app != NULL) 4175 map->map_app = newstr(map->map_app); 4176 if (map->map_tapp != NULL) 4177 map->map_tapp = newstr(map->map_tapp); 4178 return true; 4179 } 4180 4181 #if NETINET6 4182 /* 4183 ** ANYNET_NTOP -- convert an IPv6 network address to printable form. 4184 ** 4185 ** Parameters: 4186 ** s6a -- a pointer to an in6_addr structure. 4187 ** dst -- buffer to store result in 4188 ** dst_len -- size of dst buffer 4189 ** 4190 ** Returns: 4191 ** A printable version of that structure. 4192 */ 4193 4194 char * 4195 anynet_ntop(s6a, dst, dst_len) 4196 struct in6_addr *s6a; 4197 char *dst; 4198 size_t dst_len; 4199 { 4200 register char *ap; 4201 4202 if (IN6_IS_ADDR_V4MAPPED(s6a)) 4203 ap = (char *) inet_ntop(AF_INET, 4204 &s6a->s6_addr[IN6ADDRSZ - INADDRSZ], 4205 dst, dst_len); 4206 else 4207 { 4208 char *d; 4209 size_t sz; 4210 4211 /* Save pointer to beginning of string */ 4212 d = dst; 4213 4214 /* Add IPv6: protocol tag */ 4215 sz = sm_strlcpy(dst, "IPv6:", dst_len); 4216 if (sz >= dst_len) 4217 return NULL; 4218 dst += sz; 4219 dst_len -= sz; 4220 ap = (char *) inet_ntop(AF_INET6, s6a, dst, dst_len); 4221 4222 /* Restore pointer to beginning of string */ 4223 if (ap != NULL) 4224 ap = d; 4225 } 4226 return ap; 4227 } 4228 4229 /* 4230 ** ANYNET_PTON -- convert printed form to network address. 4231 ** 4232 ** Wrapper for inet_pton() which handles IPv6: labels. 4233 ** 4234 ** Parameters: 4235 ** family -- address family 4236 ** src -- string 4237 ** dst -- destination address structure 4238 ** 4239 ** Returns: 4240 ** 1 if the address was valid 4241 ** 0 if the address wasn't parseable 4242 ** -1 if error 4243 */ 4244 4245 int 4246 anynet_pton(family, src, dst) 4247 int family; 4248 const char *src; 4249 void *dst; 4250 { 4251 if (family == AF_INET6 && sm_strncasecmp(src, "IPv6:", 5) == 0) 4252 src += 5; 4253 return inet_pton(family, src, dst); 4254 } 4255 #endif /* NETINET6 */ 4256 /* 4257 ** ANYNET_NTOA -- convert a network address to printable form. 4258 ** 4259 ** Parameters: 4260 ** sap -- a pointer to a sockaddr structure. 4261 ** 4262 ** Returns: 4263 ** A printable version of that sockaddr. 4264 */ 4265 4266 #ifdef USE_SOCK_STREAM 4267 4268 # if NETLINK 4269 # include <net/if_dl.h> 4270 # endif /* NETLINK */ 4271 4272 char * 4273 anynet_ntoa(sap) 4274 register SOCKADDR *sap; 4275 { 4276 register char *bp; 4277 register char *ap; 4278 int l; 4279 static char buf[100]; 4280 4281 /* check for null/zero family */ 4282 if (sap == NULL) 4283 return "NULLADDR"; 4284 if (sap->sa.sa_family == 0) 4285 return "0"; 4286 4287 switch (sap->sa.sa_family) 4288 { 4289 # if NETUNIX 4290 case AF_UNIX: 4291 if (sap->sunix.sun_path[0] != '\0') 4292 (void) sm_snprintf(buf, sizeof buf, "[UNIX: %.64s]", 4293 sap->sunix.sun_path); 4294 else 4295 (void) sm_strlcpy(buf, "[UNIX: localhost]", sizeof buf); 4296 return buf; 4297 # endif /* NETUNIX */ 4298 4299 # if NETINET 4300 case AF_INET: 4301 return (char *) inet_ntoa(sap->sin.sin_addr); 4302 # endif /* NETINET */ 4303 4304 # if NETINET6 4305 case AF_INET6: 4306 ap = anynet_ntop(&sap->sin6.sin6_addr, buf, sizeof buf); 4307 if (ap != NULL) 4308 return ap; 4309 break; 4310 # endif /* NETINET6 */ 4311 4312 # if NETLINK 4313 case AF_LINK: 4314 (void) sm_snprintf(buf, sizeof buf, "[LINK: %s]", 4315 link_ntoa((struct sockaddr_dl *) &sap->sa)); 4316 return buf; 4317 # endif /* NETLINK */ 4318 default: 4319 /* this case is needed when nothing is #defined */ 4320 /* in order to keep the switch syntactically correct */ 4321 break; 4322 } 4323 4324 /* unknown family -- just dump bytes */ 4325 (void) sm_snprintf(buf, sizeof buf, "Family %d: ", sap->sa.sa_family); 4326 bp = &buf[strlen(buf)]; 4327 ap = sap->sa.sa_data; 4328 for (l = sizeof sap->sa.sa_data; --l >= 0; ) 4329 { 4330 (void) sm_snprintf(bp, SPACELEFT(buf, bp), "%02x:", 4331 *ap++ & 0377); 4332 bp += 3; 4333 } 4334 *--bp = '\0'; 4335 return buf; 4336 } 4337 /* 4338 ** HOSTNAMEBYANYADDR -- return name of host based on address 4339 ** 4340 ** Parameters: 4341 ** sap -- SOCKADDR pointer 4342 ** 4343 ** Returns: 4344 ** text representation of host name. 4345 ** 4346 ** Side Effects: 4347 ** none. 4348 */ 4349 4350 char * 4351 hostnamebyanyaddr(sap) 4352 register SOCKADDR *sap; 4353 { 4354 register struct hostent *hp; 4355 # if NAMED_BIND 4356 int saveretry; 4357 # endif /* NAMED_BIND */ 4358 # if NETINET6 4359 struct in6_addr in6_addr; 4360 # endif /* NETINET6 */ 4361 4362 # if NAMED_BIND 4363 /* shorten name server timeout to avoid higher level timeouts */ 4364 saveretry = _res.retry; 4365 if (_res.retry * _res.retrans > 20) 4366 _res.retry = 20 / _res.retrans; 4367 # endif /* NAMED_BIND */ 4368 4369 switch (sap->sa.sa_family) 4370 { 4371 # if NETINET 4372 case AF_INET: 4373 hp = sm_gethostbyaddr((char *) &sap->sin.sin_addr, 4374 INADDRSZ, AF_INET); 4375 break; 4376 # endif /* NETINET */ 4377 4378 # if NETINET6 4379 case AF_INET6: 4380 hp = sm_gethostbyaddr((char *) &sap->sin6.sin6_addr, 4381 IN6ADDRSZ, AF_INET6); 4382 break; 4383 # endif /* NETINET6 */ 4384 4385 # if NETISO 4386 case AF_ISO: 4387 hp = sm_gethostbyaddr((char *) &sap->siso.siso_addr, 4388 sizeof sap->siso.siso_addr, AF_ISO); 4389 break; 4390 # endif /* NETISO */ 4391 4392 # if NETUNIX 4393 case AF_UNIX: 4394 hp = NULL; 4395 break; 4396 # endif /* NETUNIX */ 4397 4398 default: 4399 hp = sm_gethostbyaddr(sap->sa.sa_data, sizeof sap->sa.sa_data, 4400 sap->sa.sa_family); 4401 break; 4402 } 4403 4404 # if NAMED_BIND 4405 _res.retry = saveretry; 4406 # endif /* NAMED_BIND */ 4407 4408 # if NETINET || NETINET6 4409 if (hp != NULL && hp->h_name[0] != '[' 4410 # if NETINET6 4411 && inet_pton(AF_INET6, hp->h_name, &in6_addr) != 1 4412 # endif /* NETINET6 */ 4413 # if NETINET 4414 && inet_addr(hp->h_name) == INADDR_NONE 4415 # endif /* NETINET */ 4416 ) 4417 { 4418 char *name; 4419 4420 name = denlstring((char *) hp->h_name, true, true); 4421 # if NETINET6 4422 if (name == hp->h_name) 4423 { 4424 static char n[MAXNAME + 1]; 4425 4426 /* Copy the string, hp->h_name is about to disappear */ 4427 (void) sm_strlcpy(n, name, sizeof n); 4428 name = n; 4429 } 4430 freehostent(hp); 4431 # endif /* NETINET6 */ 4432 return name; 4433 } 4434 # endif /* NETINET || NETINET6 */ 4435 4436 # if NETINET6 4437 if (hp != NULL) 4438 { 4439 freehostent(hp); 4440 hp = NULL; 4441 } 4442 # endif /* NETINET6 */ 4443 4444 # if NETUNIX 4445 if (sap->sa.sa_family == AF_UNIX && sap->sunix.sun_path[0] == '\0') 4446 return "localhost"; 4447 # endif /* NETUNIX */ 4448 { 4449 static char buf[203]; 4450 4451 (void) sm_snprintf(buf, sizeof buf, "[%.200s]", 4452 anynet_ntoa(sap)); 4453 return buf; 4454 } 4455 } 4456 #endif /* USE_SOCK_STREAM */ 4457