xref: /netbsd-src/lib/libwrap/eval.c (revision e1a2f47f1264dd9755e9e747d45ba016dff2334f)
1*e1a2f47fSmatt /*	$NetBSD: eval.c,v 1.7 2012/03/21 10:10:37 matt Exp $	*/
2d6ddaab4Schristos 
3541be36cSmrg  /*
4541be36cSmrg   * Routines for controlled evaluation of host names, user names, and so on.
5541be36cSmrg   * They are, in fact, wrappers around the functions that are specific for
6541be36cSmrg   * the sockets or TLI programming interfaces. The request_info and host_info
7541be36cSmrg   * structures are used for result cacheing.
8541be36cSmrg   *
9541be36cSmrg   * These routines allows us to postpone expensive operations until their
10541be36cSmrg   * results are really needed. Examples are hostname lookups and double
11541be36cSmrg   * checks, or username lookups. Information that cannot be retrieved is
12541be36cSmrg   * given the value "unknown" ("paranoid" in case of hostname problems).
13541be36cSmrg   *
14541be36cSmrg   * When ALWAYS_HOSTNAME is off, hostname lookup is done only when required by
15541be36cSmrg   * tcpd paranoid mode, by access control patterns, or by %letter expansions.
16541be36cSmrg   *
17541be36cSmrg   * When ALWAYS_RFC931 mode is off, user lookup is done only when required by
18541be36cSmrg   * access control patterns or %letter expansions.
19541be36cSmrg   *
20541be36cSmrg   * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
21541be36cSmrg   */
22541be36cSmrg 
23d6ddaab4Schristos #include <sys/cdefs.h>
24541be36cSmrg #ifndef lint
25d6ddaab4Schristos #if 0
26541be36cSmrg static char sccsid[] = "@(#) eval.c 1.3 95/01/30 19:51:45";
27d6ddaab4Schristos #else
28*e1a2f47fSmatt __RCSID("$NetBSD: eval.c,v 1.7 2012/03/21 10:10:37 matt Exp $");
29d6ddaab4Schristos #endif
30541be36cSmrg #endif
31541be36cSmrg 
32541be36cSmrg /* System libraries. */
33541be36cSmrg 
34541be36cSmrg #include <stdio.h>
35541be36cSmrg #include <string.h>
36541be36cSmrg 
37541be36cSmrg /* Local stuff. */
38541be36cSmrg 
39541be36cSmrg #include "tcpd.h"
40541be36cSmrg 
41541be36cSmrg  /*
42541be36cSmrg   * When a string has the value STRING_UNKNOWN, it means: don't bother, I
43541be36cSmrg   * tried to look up the data but it was unavailable for some reason. When a
44541be36cSmrg   * host name has the value STRING_PARANOID it means there was a name/address
45541be36cSmrg   * conflict.
46541be36cSmrg   */
47541be36cSmrg char    unknown[] = STRING_UNKNOWN;
48541be36cSmrg char    paranoid[] = STRING_PARANOID;
49541be36cSmrg 
50541be36cSmrg /* eval_user - look up user name */
51541be36cSmrg 
52*e1a2f47fSmatt char   *
eval_user(struct request_info * request)53*e1a2f47fSmatt eval_user(struct request_info *request)
54541be36cSmrg {
55541be36cSmrg     if (request->user[0] == 0) {
563ba1803eSitojun 	(void)strlcpy(request->user, unknown, sizeof(request->user));
57541be36cSmrg 	if (request->sink == 0 && request->client->sin && request->server->sin)
58541be36cSmrg 	    rfc931(request->client->sin, request->server->sin, request->user);
59541be36cSmrg     }
60541be36cSmrg     return (request->user);
61541be36cSmrg }
62541be36cSmrg 
63541be36cSmrg /* eval_hostaddr - look up printable address */
64541be36cSmrg 
65*e1a2f47fSmatt char   *
eval_hostaddr(struct host_info * host)66*e1a2f47fSmatt eval_hostaddr(struct host_info *host)
67541be36cSmrg {
68541be36cSmrg     if (host->addr[0] == 0) {
693ba1803eSitojun 	(void)strlcpy(host->addr, unknown, sizeof(host->addr));
70541be36cSmrg 	if (host->request->hostaddr != 0)
71541be36cSmrg 	    host->request->hostaddr(host);
72541be36cSmrg     }
73541be36cSmrg     return (host->addr);
74541be36cSmrg }
75541be36cSmrg 
76541be36cSmrg /* eval_hostname - look up host name */
77541be36cSmrg 
78*e1a2f47fSmatt char   *
eval_hostname(struct host_info * host)79*e1a2f47fSmatt eval_hostname(struct host_info *host)
80541be36cSmrg {
81541be36cSmrg     if (host->name[0] == 0) {
823ba1803eSitojun 	(void)strlcpy(host->name, unknown, sizeof(host->name));
83541be36cSmrg 	if (host->request->hostname != 0)
84541be36cSmrg 	    host->request->hostname(host);
85541be36cSmrg     }
86541be36cSmrg     return (host->name);
87541be36cSmrg }
88541be36cSmrg 
89541be36cSmrg /* eval_hostinfo - return string with host name (preferred) or address */
90541be36cSmrg 
91*e1a2f47fSmatt char   *
eval_hostinfo(struct host_info * host)92*e1a2f47fSmatt eval_hostinfo(struct host_info *host)
93541be36cSmrg {
94541be36cSmrg     char   *hostname;
95541be36cSmrg 
96541be36cSmrg #ifndef ALWAYS_HOSTNAME				/* no implicit host lookups */
97541be36cSmrg     if (host->name[0] == 0)
98541be36cSmrg 	return (eval_hostaddr(host));
99541be36cSmrg #endif
100541be36cSmrg     hostname = eval_hostname(host);
101541be36cSmrg     if (HOSTNAME_KNOWN(hostname)) {
102541be36cSmrg 	return (host->name);
103541be36cSmrg     } else {
104541be36cSmrg 	return (eval_hostaddr(host));
105541be36cSmrg     }
106541be36cSmrg }
107541be36cSmrg 
108541be36cSmrg /* eval_client - return string with as much about the client as we know */
109541be36cSmrg 
110*e1a2f47fSmatt char   *
eval_client(struct request_info * request)111*e1a2f47fSmatt eval_client(struct request_info *request)
112541be36cSmrg {
113541be36cSmrg     static char both[2 * STRING_LENGTH];
114541be36cSmrg     char   *hostinfo = eval_hostinfo(request->client);
115541be36cSmrg 
116541be36cSmrg #ifndef ALWAYS_RFC931				/* no implicit user lookups */
117541be36cSmrg     if (request->user[0] == 0)
118541be36cSmrg 	return (hostinfo);
119541be36cSmrg #endif
120541be36cSmrg     if (STR_NE(eval_user(request), unknown)) {
1219cd5492cSmrg 	(void)snprintf(both, sizeof both, "%s@%s", request->user, hostinfo);
122541be36cSmrg 	return (both);
123541be36cSmrg     } else {
124541be36cSmrg 	return (hostinfo);
125541be36cSmrg     }
126541be36cSmrg }
127541be36cSmrg 
128541be36cSmrg /* eval_server - return string with as much about the server as we know */
129541be36cSmrg 
130*e1a2f47fSmatt char   *
eval_server(struct request_info * request)131*e1a2f47fSmatt eval_server(struct request_info *request)
132541be36cSmrg {
133541be36cSmrg     static char both[2 * STRING_LENGTH];
134541be36cSmrg     char   *host = eval_hostinfo(request->server);
135541be36cSmrg     char   *daemon = eval_daemon(request);
136541be36cSmrg 
137541be36cSmrg     if (STR_NE(host, unknown)) {
1389cd5492cSmrg 	(void)snprintf(both, sizeof both, "%s@%s", daemon, host);
139541be36cSmrg 	return (both);
140541be36cSmrg     } else {
141541be36cSmrg 	return (daemon);
142541be36cSmrg     }
143541be36cSmrg }
144