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