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