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