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