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