1N/A * Copyright (c) 1998-2007, 2009, 2010 Sendmail, Inc. and its suppliers. 1N/A * All rights reserved. 1N/A * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 1N/A * Copyright (c) 1988, 1993 1N/A * The Regents of the University of California. All rights reserved. 1N/A * By using this file, you agree to the terms and conditions set 1N/A * forth in the LICENSE file which can be found at the top level of 1N/A * the sendmail distribution. 1N/A#
endif /* defined(SOCK_STREAM) || defined(__GNU_LIBRARY__) */ 1N/A#
endif /* NETINET || NETINET6 */ 1N/A#
endif /* ! NO_DATA */ 1N/A#
endif /* NAMED_BIND */ 1N/A#
endif /* defined(USE_SOCK_STREAM) */ 1N/A#
endif /* STARTTLS */ 1N/A#
endif /* ! IPOPTION */ 1N/A#
else /* HAS_IN_H */ 1N/A#
endif /* ! IPOPTION */ 1N/A#
endif /* HAS_IN_H */ 1N/A#
endif /* IP_SRCROUTE && NETINET */ 1N/A** DAEMON.C -- routines to use when running as a daemon. 1N/A** This entire file is highly dependent on the 4.2 BSD 1N/A** interprocess communication primitives. No attempt has 1N/A** been made to make this file portable to Version 7, 1N/A** Version 6, MPX files, etc. If you should try such a 1N/A** thing yourself, I recommend chucking the entire file 1N/A** and starting from scratch. Basic semantics are: 1N/A** Opens a port and initiates a connection. 1N/A** Returns in a child. Must set InChannel and 1N/A** OutChannel appropriately. 1N/A** Close any open files associated with getting 1N/A** the connection; this is used when running the queue, 1N/A** etc., to avoid having extra file descriptors during 1N/A** the queue run and to avoid confusing the network 1N/A** code (if it cares). 1N/A** makeconnection(host, port, mci, e, enough) 1N/A** Make a connection to the named host on the given 1N/A** port. Returns zero on success, else an exit status 1N/A** describing the error. 1N/A** host_map_lookup(map, hbuf, avp, pstat) 1N/A** Convert the entry in hbuf into a canonical form. 1N/A** GETREQUESTS -- open mail IPC port and get requests. 1N/A** e -- the current envelope. 1N/A** Waits until some interesting activity occurs. When 1N/A** it does, a child is created to process it, and the 1N/A** parent waits for completion. Return from this 1N/A** routine is always in the child. The file pointers 1N/A** "InChannel" and "OutChannel" should be set to point 1N/A** to the communication channel. 1N/A** May restart persistent queue runners if they have ended 1N/A#
endif /* _FFR_QUEUE_RUN_PARANOIA */ 1N/A#
endif /* NETUNIX */ 1N/A /* initialize data for function that generates queue ids */ 1N/A ** Try to actually open the connection. 1N/A /* get a socket for the SMTP connection */ 1N/A "daemon could not open control socket %s: %s",
1N/A /* If there are any queue runners released reapchild() co-ord's */ 1N/A /* write the pid to file, command line args to syslog */ 1N/A /* Add parent process as first item */ 1N/A#
endif /* STARTTLS */ 1N/A /* see if we are rejecting connections */ 1N/A ** XXX do this call outside the loop? 1N/A ** no: refuse_connections may sleep(). 1N/A /* close socket so peer fails quickly */ 1N/A /* refuse connections for next 15 seconds */ 1N/A "accepting connections again for daemon %s",
1N/A /* arrange to (re)open the socket if needed */ 1N/A /* May have been sleeping above, check again */ 1N/A /* check for disaster */ 1N/A "daemon process doesn't have $j in $=w; see syslog");
1N/A "daemon process $j lost dot; see syslog");
1N/A ** Andrew Sun <asun@ieps-sun.ml.com> claims that this will 1N/A ** fix the SVr4 problem. But it seems to have gone away, 1N/A ** so is it worth doing this? 1N/A /* wait for a connection */ 1N/A "accepting connections");
1N/A /* Did someone signal while waiting? */ 1N/A#
endif /* _FFR_QUEUE_RUN_PARANOIA */ 1N/A ** set lastrun unconditionally to avoid 1N/A ** calling checkqueuerunner() all the time. 1N/A ** That's also why we currently ignore the 1N/A ** result of the function call. 1N/A#
endif /* _FFR_QUEUE_RUN_PARANOIA */ 1N/A /* look "round-robin" for an active socket */ 1N/A ** If remote side closes before 1N/A ** accept() finishes, sockaddr 1N/A ** might not be fully filled in. 1N/A#
endif /* BSD4_4_SOCKADDR */ 1N/A ** If remote side closes before 1N/A ** accept() finishes, sockaddr 1N/A ** might not be fully filled in. 1N/A#
endif /* BSD4_4_SOCKADDR */ 1N/A /* No daemon to service */ 1N/A /* let's ignore these temporary errors */ 1N/A#
endif /* ECONNABORTED */ 1N/A#
endif /* EWOULDBLOCK */ 1N/A /* arrange to re-open socket next time around */ 1N/A ** Give time for bound socket to be released. 1N/A ** This creates a denial-of-service if you can 1N/A ** force accept() to fail on affected systems. 1N/A#
endif /* SO_REUSEADDR_IS_BROKEN */ 1N/A /* set some daemon related macros */ 1N/A#
endif /* NETUNIX */ 1N/A#
endif /* _FFR_DAEMON_NETUNIX */ 1N/A#
endif /* NETINET6 */ 1N/A ** If connection rate is exceeded here, connection shall be 1N/A ** refused later by a new call after fork() by the 1N/A ** validate_connection() function. Closing the connection 1N/A ** at this point violates RFC 2821. 1N/A ** Do NOT remove this call, its side effects are needed. 1N/A ** Create a subprocess to process the mail. 1N/A ** Advance state of PRNG. 1N/A ** This is necessary because otherwise all child processes 1N/A ** will produce the same PRN sequence and hence the selection 1N/A ** of a queue directory (and other things, e.g., MX selection) 1N/A ** are not "really" random. 1N/A /* XXX get some better "random" data? */ 1N/A#
endif /* STARTTLS */ 1N/A ** Update MX records for FallbackMX. 1N/A ** Let's hope this is fast otherwise we screw up the 1N/A#
endif /* NAMED_BIND */ 1N/A /* don't fork, handle connection in this process */ 1N/A ** Create a pipe to keep the child from writing to 1N/A ** the socket until after the parent has closed 1N/A ** it. Otherwise the parent may hang if the child 1N/A ** has closed it first. 1N/A ** CHILD -- return to caller. 1N/A ** Collect verified idea of sending host. 1N/A ** Verify calling user id if possible here. 1N/A /* Reset global flags */ 1N/A /* turn on profiling */ 1N/A ** Initialize exception stack and default exception 1N/A ** handler for child process. 1N/A /* Avoid SMTP daemon actions if control command */ 1N/A /* Add control socket process */ 1N/A "console socket child",
1N/A /* clean up background delivery children */ 1N/A /* Add parent process as first child item */ 1N/A /* don't schedule queue runs if ETRN */ 1N/A ** Hack: override global variables if 1N/A ** the corresponding DaemonPortOption 1N/A#
endif /* _FFR_SS_PER_DAEMON */ 1N/A ** Wait for the parent to close the write end 1N/A ** of the pipe, which we will see as an EOF. 1N/A ** This guarantees that we won't write to the 1N/A ** socket until after the parent has closed 1N/A /* close the write end of the pipe */ 1N/A /* we shouldn't be interrupted, but ... */ 1N/A /* control socket processing */ 1N/A /* determine host name */ 1N/A syserr(
"cannot open SMTP server channel, fd=%d",
1N/A message(
"421 4.4.5 Too many SMTP sessions for this host");
1N/A /* find out name for interface of connection */ 1N/A ** Do this only if it is not the loopback 1N/A /* parent -- keep track of children */ 1N/A "control socket server child");
1N/A "SMTP server child for %s",
1N/A /* close the read end of the synchronization pipe */ 1N/A /* close the port so that others will hang (for a while) */ 1N/A /* release the child by closing the read end of the sync pipe */ 1N/A /* set the filters for this daemon */ 1N/A** GETREQUESTS_CHECKDISKSPACE -- check available diskspace. 1N/A** Modifies Daemon flags (D_ETRNONLY) if not enough disk space. 1N/A /* Check if there is available disk space in all queue groups. */ 1N/A /* log only if not logged before */ 1N/A "rejecting new messages: min free: %ld",
1N/A "rejecting new messages: min free: %ld",
1N/A /* log only if not logged before */ 1N/A "accepting new messages (again)");
1N/A /* title will be set later */ 1N/A /* only check disk space once a minute */ 1N/A** OPENDAEMONSOCKET -- open SMTP socket 1N/A** Deals with setting all appropriate options. 1N/A** d -- the structure for the daemon to open. 1N/A** firsttime -- set if this is the initial open. 1N/A** Size in bytes of the daemon socket addr. 1N/A** Leaves DaemonSocket set to the open socket. 1N/A** Exits if the socket cannot be created. 1N/A /* if not safe, don't use it */ 1N/A syserr(
"opendaemonsocket: daemon %s: unsafe domain socket %s",
1N/A /* Don't try to overtake an existing socket */ 1N/A#
endif /* NETUNIX */ 1N/A#
endif /* _FFR_DOMAIN_NETUNIX */ 1N/A syserr(
"opendaemonsocket: daemon %s: can't create server SMTP socket",
1N/A syserr(
"opendaemonsocket: daemon %s: optional socket disabled",
1N/A "daemon %s: problem creating SMTP socket",
1N/A syserr(
"opendaemonsocket: daemon %s: server SMTP socket (%d) too large",
1N/A /* turn on network debugging? */ 1N/A#
endif /* SO_RCVBUF */ 1N/A#
endif /* SO_SNDBUF */ 1N/A syserr(
"opendaemonsocket: daemon %s: failed to %s close-on-exec flag: %s",
1N/A#
endif /* NETUNIX */ 1N/A#
endif /* _FFR_DAEMON_NETUNIX */ 1N/A#
endif /* NETINET6 */ 1N/A /* probably another daemon already */ 1N/A syserr(
"opendaemonsocket: daemon %s: cannot bind",
1N/A syserr(
"opendaemonsocket: daemon %s: cannot listen",
1N/A syserr(
"!opendaemonsocket: daemon %s: server SMTP socket wedged: exiting",
1N/A return -
1;
/* avoid compiler warning on IRIX */ 1N/A** SETUPDAEMON -- setup socket for daemon 1N/A** daemonaddr -- socket for daemon 1N/A** port number on which daemon should run 1N/Astatic unsigned short 1N/A ** Set up the address for the mailer. 1N/A#
endif /* NETINET6 */ 1N/A /* unknown protocol */ 1N/A#
else /* NO_GETSERVBYNAME */ 1N/A syserr(
"554 5.3.5 service \"smtp\" unknown");
1N/A#
endif /* NO_GETSERVBYNAME */ 1N/A#
endif /* NETINET6 */ 1N/A /* unknown protocol */ 1N/A** CLRDAEMON -- reset the daemon connection 1N/A** releases any resources used by the passive daemon. 1N/A** GETMODIFIERS -- get modifier flags 1N/A** v -- the modifiers (input text line). 1N/A** modifiers -- pointer to flag field to represent modifiers. 1N/A** (xallocat()ed) string representation of modifiers. 1N/A** fills in modifiers. 1N/A /* maximum length of flags: upper case Option -> "OO " */ 1N/A /* is someone joking? */ 1N/A if (l < 0 || l >
256)
1N/A "getmodifiers too long, ignored");
1N/A for (h = v; *h !=
'\0'; h++)
1N/A** CHKDAEMONMODIFIERS -- check whether all daemons have set a flag. 1N/A** flag -- the flag to test. 1N/A** true iff all daemons have set flag. 1N/A** SETSOCKADDROPTIONS -- set options for SOCKADDR (daemon or client) 1N/A** p -- the options line. 1N/A** d -- the daemon structure to fill in. 1N/A#
endif /* _FFR_SS_PER_DAEMON */ 1N/A case 'A':
/* address */ 1N/A#
endif /* !_FFR_DPO_CS */ 1N/A case 'D':
/* DeliveryMode */ 1N/A case 'd':
/* delayLA */ 1N/A case 'F':
/* address family */ 1N/A#
endif /* !_FFR_DPO_CS */ 1N/A#
endif /* NETUNIX */ 1N/A#
endif /* _FFR_DAEMON_NETUNIX */ 1N/A#
endif /* NETINET6 */ 1N/A syserr(
"554 5.3.5 Unknown address family %s in Family=option",
1N/A#
endif /* !_FFR_DPO_CS */ 1N/A case 'L':
/* listen queue size */ 1N/A#
endif /* !_FFR_DPO_CS */ 1N/A case 'M':
/* modifiers (flags) */ 1N/A#
endif /* !_FFR_DPO_CS */ 1N/A case 'N':
/* name */ 1N/A#
endif /* !_FFR_DPO_CS */ 1N/A case 'P':
/* port */ 1N/A#
endif /* !_FFR_DPO_CS */ 1N/A case 'R':
/* receive buffer size */ 1N/A case 'S':
/* send buffer size */ 1N/A#
endif /* !_FFR_DPO_CS */ 1N/A case 'T':
/* SuperSafe */ 1N/A "Warning: SuperSafe=PostMilter requires Milter support (-DMILTER)\n");
1N/A#
endif /* _FFR_SS_PER_DAEMON */ 1N/A syserr(
"554 5.3.5 PortOptions parameter \"%s\" unknown",
1N/A /* Check addr and port after finding family */ 1N/A syserr(
"setsockaddroptions: domain socket name too long: %s > %d",
1N/A /* file safety check done in opendaemonsocket() */ 1N/A#
endif /* NETUNIX */ 1N/A#
endif /* _FFR_DAEMON_NETUNIX */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A syserr(
"554 5.3.5 address= option unsupported for family %d",
1N/A#
else /* NO_GETSERVBYNAME */ 1N/A#
endif /* NO_GETSERVBYNAME */ 1N/A#
else /* NO_GETSERVBYNAME */ 1N/A#
endif /* NO_GETSERVBYNAME */ 1N/A#
endif /* NETINET6 */ 1N/A /* assume two byte transport selector */ 1N/A#
else /* NO_GETSERVBYNAME */ 1N/A#
endif /* NO_GETSERVBYNAME */ 1N/A syserr(
"554 5.3.5 Port= option unsupported for family %d",
1N/A** SETDAEMONOPTIONS -- set options for running the MTA daemon 1N/A** p -- the options line. 1N/A** true if successful, false otherwise. 1N/A** increments number of daemons. 1N/A** INITDAEMON -- initialize daemon if not yet done. 1N/A** initializes structure for one daemon. 1N/A** SETCLIENTOPTIONS -- set options for running the client 1N/A** p -- the options line. 1N/A /* grab what we need */ 1N/A** ADDR_FAMILY -- determine address family from address 1N/A** addr -- the string representation of the address 1N/A** AF_INET, AF_INET6 or AF_UNSPEC 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETUNIX */ 1N/A#
endif /* _FFR_DAEMON_NETUNIX */ 1N/A** CHKCLIENTMODIFIERS -- check whether all clients have set a flag. 1N/A** flag -- the flag to test. 1N/A** true iff all configured clients have set the flag. 1N/A** SETUP_DAEMON_FILTERS -- Parse per-socket filters 1N/A /* no need to configure the daemons */ 1N/A** MAKECONNECTION -- make a connection to an SMTP socket on a machine. 1N/A** host -- the name of the host. 1N/A** port -- the port number to connect to. 1N/A** mci -- a pointer to the mail connection information 1N/A** structure to be filled in. 1N/A** e -- the current envelope. 1N/A** enough -- time at which to stop further connection attempts. 1N/A** (0 means no limit) 1N/A** An exit code telling whether the connection could be 1N/A** made and if not why not. 1N/A#
endif /* NETINET6 */ 1N/A /* retranslate {daemon_flags} into bitmap */ 1N/A for (; *p !=
'\0'; p++)
1N/A#
endif /* NETINET6 */ 1N/A /* Set up the address for outgoing connection. */ 1N/A#
endif /* NETINET6 */ 1N/A /* infer the address family from the address itself */ 1N/A "IPv6:::ffff:%s", p);
1N/A#
endif /* NETINET6 */ 1N/A syserr(
"554 5.3.5 Address= option unsupported for family %d",
1N/A /* D_BINDIF not set or not available, fallback to ClientPortOptions */ 1N/A#
endif /* NETINET6 */ 1N/A ** Set up the address for the mailer. 1N/A ** Accept "[a.b.c.d]" syntax for host name. 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A /* try it as a host name (avoid MX lookup) */ 1N/A#
endif /* NAMED_BIND */ 1N/A#
endif /* NAMED_BIND */ 1N/A "553 Invalid numeric domain spec \"%s\"",
1N/A /* contortion to get around SGI cc complaints */ 1N/A#
endif /* NAMED_BIND */ 1N/A#
endif /* NAMED_BIND */ 1N/A /* check for name server timeouts */ 1N/A ** An attempt with family AF_INET may 1N/A ** succeed By skipping the next section 1N/A ** of code, we will try AF_INET before 1N/A sm_dprintf(
"makeconnection: WorkAroundBrokenAAAA: Trying AF_INET lookup (AF_INET6 failed)\n");
1N/A#
endif /* NETINET6 */ 1N/A#
endif /* _FFR_GETHBN_ExFILE */ 1N/A#
endif /* NAMED_BIND */ 1N/A ** Try v6 first, then fall back to v4. 1N/A ** If we found a v6 address, but no v4 1N/A ** addresses, then TEMPFAIL. 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A syserr(
"makeconnection: long sa_data: family %d len %d",
1N/A ** Determine the port number. 1N/A#
else /* NO_GETSERVBYNAME */ 1N/A "makeconnection: service \"smtp\" unknown");
1N/A#
endif /* NO_GETSERVBYNAME */ 1N/A ** Ignore mapped IPv4 address since 1N/A ** there is a ClientPortOptions setting 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A /* assume two byte transport selector */ 1N/A#
endif /* NETINET6 */ 1N/A ** Try to actually open the connection. 1N/A /* if too many connections, don't bother trying */ 1N/A#
endif /* NETINET6 */ 1N/A /* save for logging */ 1N/A#
endif /* HASRRESVPORT */ 1N/A syserr(
"makeconnection: cannot create socket");
1N/A#
endif /* NETINET6 */ 1N/A syserr(
"makeconnection: setsockopt(SO_SNDBUF)");
1N/A#
endif /* SO_SNDBUF */ 1N/A syserr(
"makeconnection: setsockopt(SO_RCVBUF)");
1N/A#
endif /* SO_RCVBUF */ 1N/A /* turn on network debugging? */ 1N/A#
endif /* NETINET6 */ 1N/A syserr(
"makeconnection: cannot bind socket [%s]",
1N/A#
endif /* NETINET6 */ 1N/A ** Linux seems to hang in connect for 90 minutes (!!!). 1N/A ** Time out the connect to avoid this problem. 1N/A#
endif /* NETINET6 */ 1N/A /* couldn't connect.... figure out why */ 1N/A /* if running demand-dialed connection, try again */ 1N/A "makeconnection (%s [%s]) failed: %s",
1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A /* couldn't open connection */ 1N/A /* Don't clobber an already saved errno from v4retry */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A /* connection ok, put it into canonical form */ 1N/A syserr(
"cannot open SMTP client channel, fd=%d", s);
1N/A /* set {client_flags} */ 1N/A /* "add" {client_flags} to bitmap */ 1N/A /* look for just this one flag */ 1N/A /* find out name for Interface through which we connect */ 1N/A /* log connection information */ 1N/A "SMTP outgoing connect on %.40s",
name);
1N/A /* Use the configured HeloName as appropriate */ 1N/A ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 1N/A ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 1N/A** MAKECONNECTION_DS -- make a connection to a domain socket. 1N/A** mux_path -- the path of the socket to connect to. 1N/A** mci -- a pointer to the mail connection information 1N/A** structure to be filled in. 1N/A** An exit code telling whether the connection could be 1N/A** made and if not why not. 1N/A /* if not safe, don't connect */ 1N/A syserr(
"makeconnection_ds: unsafe domain socket %s",
1N/A /* prepare address structure */ 1N/A syserr(
"makeconnection_ds: domain socket name %s too long",
1N/A /* XXX why TEMPFAIL but 5.x.y ? */ 1N/A /* initialize domain socket */ 1N/A syserr(
"makeconnection_ds: could not create domain socket %s",
1N/A /* connect to server */ 1N/A /* connection ok, put it into canonical form */ 1N/A** SHUTDOWN_DAEMON -- Performs a clean shutdown of the daemon 1N/A** closes control socket, exits. 1N/A /* Remove named sockets */ 1N/A /* if not safe, don't use it */ 1N/A "Could not remove daemon %s socket: %s: %s",
1N/A#
endif /* NETUNIX */ 1N/A#
endif /* _FFR_DAEMON_NETUNIX */ 1N/A** RESTART_DAEMON -- Performs a clean restart of the daemon 1N/A** restarts the daemon or exits if restart fails. 1N/A /* clear the events to turn off SIGALRMs */ 1N/A "could not restart: need full path");
1N/A#
endif /* SM_CONF_SHM */ 1N/A /* close locked pid file */ 1N/A ** Want to drop to the user who started the process in all cases 1N/A ** *but* when running as "smmsp" for the clientmqueue queue run 1N/A ** daemon. In that case, UseMSP will be true, RunAsUid should not 1N/A ** be root, and RealUid should be either 0 or RunAsUid. 1N/A "could not drop privileges: %s",
1N/A ** Need to allow signals before execve() to make them "harmless". 1N/A ** However, the default action can be "terminate", so it isn't 1N/A ** really harmless. Setting signals to IGN will cause them to be 1N/A ** ignored in the new process to, so that isn't a good alternative. 1N/A /* Turn back on signals */ 1N/A /* block signals again and restore needed signals */ 1N/A /* For finis() events */ 1N/A /* For debugging finis() */ 1N/A** MYHOSTNAME -- return the name of this host. 1N/A** hostbuf -- a place to return the name of this host. 1N/A** size -- the size of hostbuf. 1N/A** A list of aliases for this host. 1N/A** Adds numeric codes to $=w. 1N/A ** It's possible that this IPv6 enabled machine doesn't 1N/A ** actually have any IPv6 interfaces and, therefore, no 1N/A ** IPv6 addresses. Fall back to AF_INET. 1N/A#
endif /* NETINET && NETINET6 */ 1N/A ** If there is still no dot in the name, try looking for a 1N/A ** If _still_ no dot, wait for a while and try again -- it is 1N/A ** possible that some service is starting up. This can result 1N/A ** in excessive delays if the system is badly configured, but 1N/A ** there really isn't a way around that, particularly given that 1N/A ** the config file hasn't been read at this point. 1N/A ** All in all, a bit of a mess. 1N/A "My unqualified host name (%s) unknown; sleeping for retry",
1N/A message(
"My unqualified host name (%s) unknown; sleeping for retry",
1N/A "unable to qualify my own domain name (%s) -- using short name",
1N/A message(
"WARNING: unable to qualify my own domain name (%s) -- using short name",
1N/A** ADDRCMP -- compare two host addresses 1N/A** hp -- hostent structure for the first address 1N/A** ha -- actual first address 1N/A** sa -- second address 1N/A** 0 -- if ha and sa match 1N/A** else -- they don't match 1N/A#
endif /* NETINET6 */ 1N/A /* Straight binary comparison */ 1N/A /* If IPv4-mapped IPv6 address, compare the IPv4 section */ 1N/A#
endif /* NETINET6 */ 1N/A** GETAUTHINFO -- get the real host name associated with a file descriptor 1N/A** Uses RFC1413 protocol to try to get info from the other end. 1N/A** fd -- the descriptor 1N/A** may_be_forged -- an outage that is set to true if the 1N/A** forward lookup of RealHostName does not match 1N/A** RealHostAddr; set to false if they do match. 1N/A** The user@host information associated with this descriptor. 1N/A ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD 1N/A ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE 1N/A#
endif /* NETINET */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* ! NO_GETSERVBYNAME */ 1N/A ** ENOTSOCK is OK: bail on anything else, but reset 1N/A ** errno in this case, so a mis-report doesn't 1N/A /* translate that to a host name */ 1N/A /* cross check RealHostName with forward DNS lookup */ 1N/A ** If RealHostAddr is an IPv6 connection with an 1N/A ** IPv4-mapped address, we need RealHostName's IPv4 1N/A ** address(es) for addrcmp() to compare against 1N/A ** Actually, we only need to do this for systems 1N/A ** which NEEDSGETIPNODE since the real getipnodebyname() 1N/A ** already does V4MAPPED address via the AI_V4MAPPEDCFG 1N/A ** flag. A better fix to this problem is to add this 1N/A ** functionality to our stub getipnodebyname(). 1N/A#
endif /* NETINET6 && NEEDSGETIPNODE */ 1N/A /* try to match the reverse against the forward lookup */ 1N/A /* XXX: Could be a temporary error on forward lookup */ 1N/A#
endif /* NETINET6 */ 1N/A /* create ident query */ 1N/A /* create local address */ 1N/A /* create foreign address */ 1N/A#
else /* NO_GETSERVBYNAME */ 1N/A ** getservbyname() consumes about 5% of the time 1N/A ** when receiving a small message (almost all of the time 1N/A ** spent in this routine). 1N/A ** Hence we store the port in a static variable 1N/A ** to save this time. 1N/A ** The portnumber shouldn't change very often... 1N/A ** This code makes the assumption that the port number 1N/A#
endif /* NO_GETSERVBYNAME */ 1N/A /* create ident query */ 1N/A /* create local address */ 1N/A /* create foreign address */ 1N/A#
else /* NO_GETSERVBYNAME */ 1N/A#
endif /* NO_GETSERVBYNAME */ 1N/A#
endif /* NETINET6 */ 1N/A /* put a timeout around the whole thing */ 1N/A /* connect to foreign IDENT server using same address as SMTP socket */ 1N/A if (p >= &
ibuf[
2] && *--p ==
'\n' && *--p ==
'\r')
1N/A /* malformed response */ 1N/A /* presumably an error string */ 1N/A /* either useridxx or malformed response */ 1N/A /* p now points to the OSTYPE field */ 1N/A /* malformed response */ 1N/A /* 1413 says don't do this -- but it's broken otherwise */ 1N/A /* p now points to the authenticated name -- copy carefully */ 1N/A /* put back the original incoming port */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* ! GET_IPOPT_DST */ 1N/A ** Extract IP source routing information. 1N/A ** Format of output for a connection from site a through b 1N/A ** loose: @site-c@site-b:site-a 1N/A ** strict: !@site-c@site-b:site-a 1N/A ** o - pointer within ipopt_list structure. 1N/A ** q - pointer within ls/ss rr route data 1N/A ** p - pointer to hbuf 1N/A ** o[1] is the length of this option, 1N/A ** including option type and 1N/A ** o[2] is the pointer into the route 1N/A ** o[3] begins the route data. 1N/A l >
240 ?
120 : l /
2,
1N/A /* q skips length and router pointer to data */ 1N/A for ( ; j >= 0; j--)
1N/A /* Skip over option */ 1N/A#
endif /* IP_SRCROUTE */ 1N/A#
endif /* IP_SRCROUTE */ 1N/A /* put back the original incoming port */ 1N/A#
endif /* NETINET6 */ 1N/A** HOST_MAP_LOOKUP -- turn a hostname into canonical form 1N/A** map -- a pointer to this map. 1N/A** name -- the (presumably unqualified) hostname. 1N/A** av -- unused -- for compatibility with other mapping 1N/A** statp -- an exit status (out parameter) -- set to 1N/A** EX_TEMPFAIL if the name server is unavailable. 1N/A** The mapping, if found. 1N/A** NULL if no mapping found. 1N/A** Looks up the host specified in hbuf. If it is not 1N/A** the canonical name for that host, return the canonical 1N/A** name (unless MF_MATCHONLY is set, which will cause the 1N/A** status only to be returned). 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NAMED_BIND */ 1N/A ** See if we have already looked up this name. If so, just 1N/A ** return it (unless expired). 1N/A syserr(
"host_map_lookup(%s): bogus NULL cache entry, errno=%d, h_errno=%d",
1N/A ** If we are running without a regular network connection (usually 1N/A ** dial-on-demand) and we are just queueing, we want to avoid DNS 1N/A ** lookups because those could try to connect to a server. 1N/A ** If first character is a bracket, then it is an address 1N/A ** lookup. Address is copied into a temporary buffer to 1N/A ** strip the brackets and to preserve name if address is 1N/A#
endif /* NAMED_BIND */ 1N/A /* set default TTL */ 1N/A#
endif /* NETINET6 */ 1N/A /* found a match -- copy out */ 1N/A /* hp->h_name is about to disappear */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NAMED_BIND */ 1N/A /* Found an answer */ 1N/A /* No match found */ 1N/A#
else /* NAMED_BIND */ 1N/A#
endif /* NAMED_BIND */ 1N/A** HOST_MAP_INIT -- initialize host class structures 1N/A** map -- a pointer to this map. 1N/A** args -- argument string. 1N/A case 'S':
/* only for consistency */ 1N/A** ANYNET_NTOP -- convert an IPv6 network address to printable form. 1N/A** s6a -- a pointer to an in6_addr structure. 1N/A** dst -- buffer to store result in 1N/A** dst_len -- size of dst buffer 1N/A** A printable version of that structure. 1N/A /* Save pointer to beginning of string */ 1N/A /* Add IPv6: protocol tag */ 1N/A /* Restore pointer to beginning of string */ 1N/A** ANYNET_PTON -- convert printed form to network address. 1N/A** Wrapper for inet_pton() which handles IPv6: labels. 1N/A** family -- address family 1N/A** dst -- destination address structure 1N/A** 1 if the address was valid 1N/A** 0 if the address wasn't parseable 1N/A#
endif /* NETINET6 */ 1N/A** ANYNET_NTOA -- convert a network address to printable form. 1N/A** sap -- a pointer to a sockaddr structure. 1N/A** A printable version of that sockaddr. 1N/A#
endif /* NETLINK */ 1N/A#
endif /* NETUNIX */ 1N/A#
endif /* NETINET */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETLINK */ 1N/A /* this case is needed when nothing is #defined */ 1N/A /* in order to keep the switch syntactically correct */ 1N/A /* unknown family -- just dump bytes */ 1N/A** HOSTNAMEBYANYADDR -- return name of host based on address 1N/A** sap -- SOCKADDR pointer 1N/A** text representation of host name. 1N/A#
endif /* NAMED_BIND */ 1N/A#
endif /* NETINET6 */ 1N/A /* shorten name server timeout to avoid higher level timeouts */ 1N/A#
endif /* NAMED_BIND */ 1N/A#
endif /* NETINET */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETUNIX */ 1N/A#
endif /* NAMED_BIND */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET */ 1N/A /* Copy the string, hp->h_name is about to disappear */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETINET || NETINET6 */ 1N/A#
endif /* NETINET6 */ 1N/A#
endif /* NETUNIX */ 1N/A#
endif /* USE_SOCK_STREAM */