# 2.11BSD#431 - /usr/src/libexec/tcpd/tli.c

##### Functions

    tli_host          X

       1:  /*
       2:   * tli_host() determines the type of transport (connected, connectionless),
       3:   * the transport address of a client host, and the transport address of a
       4:   * server endpoint. In addition, it provides methods to map a transport
       5:   * address to a printable host name or address. Socket address results are
       6:   * in static memory; tli structures are allocated from the heap.
       7:   *
       8:   * The result from the hostname lookup method is STRING_PARANOID when a host
       9:   * pretends to have someone elses name, or when a host name is available but
      10:   * could not be verified.
      11:   *
      12:   * Diagnostics are reported through syslog(3).
      13:   *
      14:   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
      15:   */
      16:
      17: #if !defined(lint) && defined(DOSCCS)
      18: static char sccsid[] = "@(#) tli.c 1.14.1 96/03/23 22:26:03";
      19: #endif
      20:
      21: #ifdef TLI
      22:
      23: /* System libraries. */
      24:
      25: #include <sys/types.h>
      26: #include <sys/param.h>
      27: #include <sys/stream.h>
      28: #include <sys/stat.h>
      29: #include <sys/mkdev.h>
      30: #include <sys/tiuser.h>
      31: #include <sys/timod.h>
      32: #include <sys/socket.h>
      33: #include <netinet/in.h>
      34: #include <stdio.h>
      35: #include <syslog.h>
      36: #include <errno.h>
      37: #include <netconfig.h>
      38: #include <netdir.h>
      39: #include <string.h>
      40:
      41: extern char *nc_sperror();
      42: extern int errno;
      43: extern int t_errno;
      44: extern char *t_errlist[];
      45: extern int t_nerr;
      46:
      47: /* Local stuff. */
      48:
      49: #include "tcpd.h"
      50:
      51: /* Forward declarations. */
      52:
      53: static void tli_endpoints();
      54: static struct netconfig *tli_transport();
      55: static void tli_hostname();
      56: static void tli_hostaddr();
      57: static void tli_cleanup();
      58: static char *tli_error();
      59: static void tli_sink();
      60:
      61: /* tli_host - look up endpoint addresses and install conversion methods */
      62:
      63: void    tli_host(request)
      64: struct request_info *request;
      65: {
      66:     static struct sockaddr_in client;
      67:     static struct sockaddr_in server;
      68:
      69:     /*
      70:      * If we discover that we are using an IP transport, pretend we never
      71:      * were here. Otherwise, use the transport-independent method and stick
      72:      * to generic network addresses. XXX hard-coded protocol family name.
      73:      */
      74:
      75:     tli_endpoints(request);
      76:     if ((request->config = tli_transport(request->fd)) != 0
      77:     && STR_EQ(request->config->nc_protofmly, "inet")) {
      78:     if (request->client->unit != 0) {
      79:         client = *(struct sockaddr_in *) request->client->unit->addr.buf;
      80:         request->client->sin = &client;
      81:     }
      82:     if (request->server->unit != 0) {
      83:         server = *(struct sockaddr_in *) request->server->unit->addr.buf;
      84:         request->server->sin = &server;
      85:     }
      86:     tli_cleanup(request);
      87:     sock_methods(request);
      88:     } else {
      89:     request->hostname = tli_hostname;
      90:     request->hostaddr = tli_hostaddr;
      91:     request->cleanup = tli_cleanup;
      92:     }
      93: }
      94:
      95: /* tli_cleanup - cleanup some dynamically-allocated data structures */
      96:
      97: static void tli_cleanup(request)
      98: struct request_info *request;
      99: {
     100:     if (request->config != 0)
     101:     freenetconfigent(request->config);
     102:     if (request->client->unit != 0)
     103:     t_free((char *) request->client->unit, T_UNITDATA);
     104:     if (request->server->unit != 0)
     105:     t_free((char *) request->server->unit, T_UNITDATA);
     106: }
     107:
     108: /* tli_endpoints - determine TLI client and server endpoint information */
     109:
     110: static void tli_endpoints(request)
     111: struct request_info *request;
     112: {
     113:     struct t_unitdata *server;
     114:     struct t_unitdata *client;
     115:     int     fd = request->fd;
     116:     int     flags;
     117:
     118:     /*
     119:      * Determine the client endpoint address. With unconnected services, peek
     120:      * at the sender address of the pending protocol data unit without
     121:      * popping it off the receive queue. This trick works because only the
     122:      * address member of the unitdata structure has been allocated.
     123:      *
     124:      * Beware of successful returns with zero-length netbufs (for example,
     125:      * Solaris 2.3 with ticlts transport). The netdir(3) routines can't
     126:      * handle that. Assume connection-less transport when TI_GETPEERNAME
     127:      * produces no usable result, even when t_rcvudata() is unable to figure
     128:      * out the peer address. Better to hang than to loop.
     129:      */
     130:
     131:     if ((client = (struct t_unitdata *) t_alloc(fd, T_UNITDATA, T_ADDR)) == 0) {
     132:     tcpd_warn("t_alloc: %s", tli_error());
     133:     return;
     134:     }
     135:     if (ioctl(fd, TI_GETPEERNAME, &client->addr) < 0 || client->addr.len == 0) {
     136:     request->sink = tli_sink;
     137:     if (t_rcvudata(fd, client, &flags) < 0 || client->addr.len == 0) {
     138:         tcpd_warn("can't get client address: %s", tli_error());
     139:         t_free((void *) client, T_UNITDATA);
     140:         return;
     141:     }
     142:     }
     143:     request->client->unit = client;
     144:
     145:     /*
     146:      * Look up the server endpoint address. This can be used for filtering on
     147:      * server address or name, or to look up the client user.
     148:      */
     149:
     150:     if ((server = (struct t_unitdata *) t_alloc(fd, T_UNITDATA, T_ADDR)) == 0) {
     151:     tcpd_warn("t_alloc: %s", tli_error());
     152:     return;
     153:     }
     154:     if (ioctl(fd, TI_GETMYNAME, &server->addr) < 0) {
     155:     tcpd_warn("TI_GETMYNAME: %m");
     156:     t_free((void *) server, T_UNITDATA);
     157:     return;
     158:     }
     159:     request->server->unit = server;
     160: }
     161:
     162: /* tli_transport - find out TLI transport type */
     163:
     164: static struct netconfig *tli_transport(fd)
     165: int     fd;
     166: {
     167:     struct stat from_client;
     168:     struct stat from_config;
     169:     void   *handlep;
     170:     struct netconfig *config;
     171:
     172:     /*
     173:      * Assuming that the network device is a clone device, we must compare
     174:      * the major device number of stdin to the minor device number of the
     175:      * devices listed in the netconfig table.
     176:      */
     177:
     178:     if (fstat(fd, &from_client) != 0) {
     179:     tcpd_warn("fstat(fd %d): %m", fd);
     180:     return (0);
     181:     }
     182:     if ((handlep = setnetconfig()) == 0) {
     183:     tcpd_warn("setnetconfig: %m");
     184:     return (0);
     185:     }
     186:     while (config = getnetconfig(handlep)) {
     187:     if (stat(config->nc_device, &from_config) == 0) {
     188:         if (minor(from_config.st_rdev) == major(from_client.st_rdev))
     189:         break;
     190:     }
     191:     }
     192:     if (config == 0) {
     193:     tcpd_warn("unable to identify transport protocol");
     194:     return (0);
     195:     }
     196:
     197:     /*
     198:      * Something else may clobber our getnetconfig() result, so we'd better
     199:      * acquire our private copy.
     200:      */
     201:
     202:     if ((config = getnetconfigent(config->nc_netid)) == 0) {
     203:     tcpd_warn("getnetconfigent(%s): %s", config->nc_netid, nc_sperror());
     204:     return (0);
     205:     }
     206:     return (config);
     207: }
     208:
     209: /* tli_hostaddr - map TLI transport address to printable address */
     210:
     211: static void tli_hostaddr(host)
     212: struct host_info *host;
     213: {
     214:     struct request_info *request = host->request;
     215:     struct netconfig *config = request->config;
     216:     struct t_unitdata *unit = host->unit;
     217:     char   *uaddr;
     218:
     219:     if (config != 0 && unit != 0
     220:     && (uaddr = taddr2uaddr(config, &unit->addr)) != 0) {
     221:     STRN_CPY(host->addr, uaddr, sizeof(host->addr));
     222:     free(uaddr);
     223:     }
     224: }
     225:
     226: /* tli_hostname - map TLI transport address to hostname */
     227:
     228: static void tli_hostname(host)
     229: struct host_info *host;
     230: {
     231:     struct request_info *request = host->request;
     232:     struct netconfig *config = request->config;
     233:     struct t_unitdata *unit = host->unit;
     234:     struct nd_hostservlist *servlist;
     235:
     236:     if (config != 0 && unit != 0
     237:     && netdir_getbyaddr(config, &servlist, &unit->addr) == ND_OK) {
     238:
     239:     struct nd_hostserv *service = servlist->h_hostservs;
     240:     struct nd_addrlist *addr_list;
     241:     int     found = 0;
     242:
     243:     if (netdir_getbyname(config, service, &addr_list) != ND_OK) {
     244:
     245:         /*
     246: 	     * Unable to verify that the name matches the address. This may
     247: 	     * be a transient problem or a botched name server setup. We
     248: 	     * decide to play safe.
     249: 	     */
     250:
     251:         tcpd_warn("can't verify hostname: netdir_getbyname(%s) failed",
     252:               service->h_host);
     253:
     254:     } else {
     255:
     256:         /*
     257: 	     * Look up the host address in the address list we just got. The
     258: 	     * comparison is done on the textual representation, because the
     259: 	     * transport address is an opaque structure that may have holes
     260: 	     * with uninitialized garbage. This approach obviously loses when
     261: 	     * the address does not have a textual representation.
     262: 	     */
     263:
     264:         char   *uaddr = eval_hostaddr(host);
     265:         char   *ua;
     266:         int     i;
     267:
     268:         for (i = 0; found == 0 && i < addr_list->n_cnt; i++) {
     269:         if ((ua = taddr2uaddr(config, &(addr_list->n_addrs[i]))) != 0) {
     270:             found = !strcmp(ua, uaddr);
     271:             free(ua);
     272:         }
     273:         }
     274:         netdir_free((void *) addr_list, ND_ADDRLIST);
     275:
     276:         /*
     277: 	     * When the host name does not map to the initial address, assume
     278: 	     * someone has compromised a name server. More likely someone
     279: 	     * botched it, but that could be dangerous, too.
     280: 	     */
     281:
     282:         if (found == 0)
     283:         tcpd_warn("host name/address mismatch: %s != %s",
     284:               host->addr, service->h_host);
     285:     }
     286:     STRN_CPY(host->name, found ? service->h_host : paranoid,
     287:          sizeof(host->name));
     288:     netdir_free((void *) servlist, ND_HOSTSERVLIST);
     289:     }
     290: }
     291:
     292: /* tli_error - convert tli error number to text */
     293:
     294: static char *tli_error()
     295: {
     296:     static char buf[40];
     297:
     298:     if (t_errno != TSYSERR) {
     299:     if (t_errno < 0 || t_errno >= t_nerr) {
     300:         sprintf(buf, "Unknown TLI error %d", t_errno);
     301:         return (buf);
     302:     } else {
     303:         return (t_errlist[t_errno]);
     304:     }
     305:     } else
     306:     return(strerror(errno));
     307: }
     308:
     309: /* tli_sink - absorb unreceived datagram */
     310:
     311: static void tli_sink(fd)
     312: int     fd;
     313: {
     314:     struct t_unitdata *unit;
     315:     int     flags;
     316:
     317:     /*
     318:      * Something went wrong. Absorb the datagram to keep inetd from looping.
     319:      * Allocate storage for address, control and data. If that fails, sleep
     320:      * for a couple of seconds in an attempt to keep inetd from looping too
     321:      * fast.
     322:      */
     323:
     324:     if ((unit = (struct t_unitdata *) t_alloc(fd, T_UNITDATA, T_ALL)) == 0) {
     325:     tcpd_warn("t_alloc: %s", tli_error());
     326:     sleep(5);
     327:     } else {
     328:     (void) t_rcvudata(fd, unit, &flags);
     329:     t_free((void *) unit, T_UNITDATA);
     330:     }
     331: }
     332:
     333: #endif /* TLI */

#### Defined functions

tli_cleanup defined in line 97; used 3 times

- in line 57, 86-91(2)

tli_endpoints defined in line 110; used 2 times

- in line 53, 75

tli_error defined in line 294; used 5 times

- in line 58, 132, 138, 151, 325

tli_host defined in line 63; used 3 times

- in /usr/src/libexec/tcpd/fromhost.c line 46
- in /usr/src/libexec/tcpd/ncr.c line 67
- in /usr/src/libexec/tcpd/tcpd.h line 139

tli_hostaddr defined in line 211; used 2 times

- in line 56, 90

tli_hostname defined in line 228; used 2 times

- in line 55, 89

tli_sink defined in line 311; used 2 times

- in line 59, 136

tli_transport defined in line 164; used 2 times

- in line 54, 76

#### Defined variables

sccsid defined in line 18; never used

Last modified: 1996-03-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 784 |