Home | History | Annotate | Line # | Download | only in libwrap
eval.c revision 1.2
      1  /*
      2   * Routines for controlled evaluation of host names, user names, and so on.
      3   * They are, in fact, wrappers around the functions that are specific for
      4   * the sockets or TLI programming interfaces. The request_info and host_info
      5   * structures are used for result cacheing.
      6   *
      7   * These routines allows us to postpone expensive operations until their
      8   * results are really needed. Examples are hostname lookups and double
      9   * checks, or username lookups. Information that cannot be retrieved is
     10   * given the value "unknown" ("paranoid" in case of hostname problems).
     11   *
     12   * When ALWAYS_HOSTNAME is off, hostname lookup is done only when required by
     13   * tcpd paranoid mode, by access control patterns, or by %letter expansions.
     14   *
     15   * When ALWAYS_RFC931 mode is off, user lookup is done only when required by
     16   * access control patterns or %letter expansions.
     17   *
     18   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
     19   */
     20 
     21 #ifndef lint
     22 static char sccsid[] = "@(#) eval.c 1.3 95/01/30 19:51:45";
     23 #endif
     24 
     25 /* System libraries. */
     26 
     27 #include <stdio.h>
     28 #include <string.h>
     29 
     30 /* Local stuff. */
     31 
     32 #include "tcpd.h"
     33 
     34  /*
     35   * When a string has the value STRING_UNKNOWN, it means: don't bother, I
     36   * tried to look up the data but it was unavailable for some reason. When a
     37   * host name has the value STRING_PARANOID it means there was a name/address
     38   * conflict.
     39   */
     40 char    unknown[] = STRING_UNKNOWN;
     41 char    paranoid[] = STRING_PARANOID;
     42 
     43 /* eval_user - look up user name */
     44 
     45 char   *eval_user(request)
     46 struct request_info *request;
     47 {
     48     if (request->user[0] == 0) {
     49 	(void)strncpy(request->user, unknown, sizeof(request->user) - 1);
     50 	if (request->sink == 0 && request->client->sin && request->server->sin)
     51 	    rfc931(request->client->sin, request->server->sin, request->user);
     52     }
     53     return (request->user);
     54 }
     55 
     56 /* eval_hostaddr - look up printable address */
     57 
     58 char   *eval_hostaddr(host)
     59 struct host_info *host;
     60 {
     61     if (host->addr[0] == 0) {
     62 	(void)strncpy(host->addr, unknown, sizeof(host->addr) - 1);
     63 	if (host->request->hostaddr != 0)
     64 	    host->request->hostaddr(host);
     65     }
     66     return (host->addr);
     67 }
     68 
     69 /* eval_hostname - look up host name */
     70 
     71 char   *eval_hostname(host)
     72 struct host_info *host;
     73 {
     74     if (host->name[0] == 0) {
     75 	(void)strncpy(host->name, unknown, sizeof(host->name) - 1);
     76 	if (host->request->hostname != 0)
     77 	    host->request->hostname(host);
     78     }
     79     return (host->name);
     80 }
     81 
     82 /* eval_hostinfo - return string with host name (preferred) or address */
     83 
     84 char   *eval_hostinfo(host)
     85 struct host_info *host;
     86 {
     87     char   *hostname;
     88 
     89 #ifndef ALWAYS_HOSTNAME				/* no implicit host lookups */
     90     if (host->name[0] == 0)
     91 	return (eval_hostaddr(host));
     92 #endif
     93     hostname = eval_hostname(host);
     94     if (HOSTNAME_KNOWN(hostname)) {
     95 	return (host->name);
     96     } else {
     97 	return (eval_hostaddr(host));
     98     }
     99 }
    100 
    101 /* eval_client - return string with as much about the client as we know */
    102 
    103 char   *eval_client(request)
    104 struct request_info *request;
    105 {
    106     static char both[2 * STRING_LENGTH];
    107     char   *hostinfo = eval_hostinfo(request->client);
    108 
    109 #ifndef ALWAYS_RFC931				/* no implicit user lookups */
    110     if (request->user[0] == 0)
    111 	return (hostinfo);
    112 #endif
    113     if (STR_NE(eval_user(request), unknown)) {
    114 	(void)snprintf(both, sizeof both, "%s@%s", request->user, hostinfo);
    115 	return (both);
    116     } else {
    117 	return (hostinfo);
    118     }
    119 }
    120 
    121 /* eval_server - return string with as much about the server as we know */
    122 
    123 char   *eval_server(request)
    124 struct request_info *request;
    125 {
    126     static char both[2 * STRING_LENGTH];
    127     char   *host = eval_hostinfo(request->server);
    128     char   *daemon = eval_daemon(request);
    129 
    130     if (STR_NE(host, unknown)) {
    131 	(void)snprintf(both, sizeof both, "%s@%s", daemon, host);
    132 	return (both);
    133     } else {
    134 	return (daemon);
    135     }
    136 }
    137