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