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