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