144743Smarkm /*
244743Smarkm  * Routines for controlled evaluation of host names, user names, and so on.
344743Smarkm  * They are, in fact, wrappers around the functions that are specific for
444743Smarkm  * the sockets or TLI programming interfaces. The request_info and host_info
544743Smarkm  * structures are used for result cacheing.
644743Smarkm  *
744743Smarkm  * These routines allows us to postpone expensive operations until their
844743Smarkm  * results are really needed. Examples are hostname lookups and double
944743Smarkm  * checks, or username lookups. Information that cannot be retrieved is
1044743Smarkm  * given the value "unknown" ("paranoid" in case of hostname problems).
1144743Smarkm  *
1244743Smarkm  * When ALWAYS_HOSTNAME is off, hostname lookup is done only when required by
1344743Smarkm  * tcpd paranoid mode, by access control patterns, or by %letter expansions.
1444743Smarkm  *
1544743Smarkm  * When ALWAYS_RFC931 mode is off, user lookup is done only when required by
1644743Smarkm  * access control patterns or %letter expansions.
1744743Smarkm  *
1844743Smarkm  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
1944743Smarkm  */
2044743Smarkm
2144743Smarkm#ifndef lint
2244743Smarkmstatic char sccsid[] = "@(#) eval.c 1.3 95/01/30 19:51:45";
2344743Smarkm#endif
2444743Smarkm
2544743Smarkm/* System libraries. */
2644743Smarkm
2744743Smarkm#include <stdio.h>
2844743Smarkm#include <string.h>
2944743Smarkm
3044743Smarkm/* Local stuff. */
3144743Smarkm
3244743Smarkm#include "tcpd.h"
3344743Smarkm
3444743Smarkm /*
3544743Smarkm  * When a string has the value STRING_UNKNOWN, it means: don't bother, I
3644743Smarkm  * tried to look up the data but it was unavailable for some reason. When a
3744743Smarkm  * host name has the value STRING_PARANOID it means there was a name/address
3844743Smarkm  * conflict.
3944743Smarkm  */
4044743Smarkmchar    unknown[] = STRING_UNKNOWN;
4144743Smarkmchar    paranoid[] = STRING_PARANOID;
4244743Smarkm
4344743Smarkm/* eval_user - look up user name */
4444743Smarkm
4544743Smarkmchar   *eval_user(request)
4644743Smarkmstruct request_info *request;
4744743Smarkm{
4844743Smarkm    if (request->user[0] == 0) {
4944743Smarkm	strcpy(request->user, unknown);
5044743Smarkm	if (request->sink == 0 && request->client->sin && request->server->sin)
5144743Smarkm	    rfc931(request->client->sin, request->server->sin, request->user);
5244743Smarkm    }
5344743Smarkm    return (request->user);
5444743Smarkm}
5544743Smarkm
5644743Smarkm/* eval_hostaddr - look up printable address */
5744743Smarkm
5844743Smarkmchar   *eval_hostaddr(host)
5944743Smarkmstruct host_info *host;
6044743Smarkm{
6144743Smarkm    if (host->addr[0] == 0) {
6244743Smarkm	strcpy(host->addr, unknown);
6344743Smarkm	if (host->request->hostaddr != 0)
6444743Smarkm	    host->request->hostaddr(host);
6544743Smarkm    }
6644743Smarkm    return (host->addr);
6744743Smarkm}
6844743Smarkm
6944743Smarkm/* eval_hostname - look up host name */
7044743Smarkm
7144743Smarkmchar   *eval_hostname(host)
7244743Smarkmstruct host_info *host;
7344743Smarkm{
7444743Smarkm    if (host->name[0] == 0) {
7544743Smarkm	strcpy(host->name, unknown);
7644743Smarkm	if (host->request->hostname != 0)
7744743Smarkm	    host->request->hostname(host);
7844743Smarkm    }
7944743Smarkm    return (host->name);
8044743Smarkm}
8144743Smarkm
8244743Smarkm/* eval_hostinfo - return string with host name (preferred) or address */
8344743Smarkm
8444743Smarkmchar   *eval_hostinfo(host)
8544743Smarkmstruct host_info *host;
8644743Smarkm{
8744743Smarkm    char   *hostname;
8844743Smarkm
8944743Smarkm#ifndef ALWAYS_HOSTNAME				/* no implicit host lookups */
9044743Smarkm    if (host->name[0] == 0)
9144743Smarkm	return (eval_hostaddr(host));
9244743Smarkm#endif
9344743Smarkm    hostname = eval_hostname(host);
9444743Smarkm    if (HOSTNAME_KNOWN(hostname)) {
9544743Smarkm	return (host->name);
9644743Smarkm    } else {
9744743Smarkm	return (eval_hostaddr(host));
9844743Smarkm    }
9944743Smarkm}
10044743Smarkm
10144743Smarkm/* eval_client - return string with as much about the client as we know */
10244743Smarkm
10344743Smarkmchar   *eval_client(request)
10444743Smarkmstruct request_info *request;
10544743Smarkm{
10644743Smarkm    static char both[2 * STRING_LENGTH];
10744743Smarkm    char   *hostinfo = eval_hostinfo(request->client);
10844743Smarkm
10944743Smarkm#ifndef ALWAYS_RFC931				/* no implicit user lookups */
11044743Smarkm    if (request->user[0] == 0)
11144743Smarkm	return (hostinfo);
11244743Smarkm#endif
11344743Smarkm    if (STR_NE(eval_user(request), unknown)) {
11444743Smarkm	sprintf(both, "%s@%s", request->user, hostinfo);
11544743Smarkm	return (both);
11644743Smarkm    } else {
11744743Smarkm	return (hostinfo);
11844743Smarkm    }
11944743Smarkm}
12044743Smarkm
12144743Smarkm/* eval_server - return string with as much about the server as we know */
12244743Smarkm
12344743Smarkmchar   *eval_server(request)
12444743Smarkmstruct request_info *request;
12544743Smarkm{
12644743Smarkm    static char both[2 * STRING_LENGTH];
12744743Smarkm    char   *host = eval_hostinfo(request->server);
12844743Smarkm    char   *daemon = eval_daemon(request);
12944743Smarkm
13044743Smarkm    if (STR_NE(host, unknown)) {
13144743Smarkm	sprintf(both, "%s@%s", daemon, host);
13244743Smarkm	return (both);
13344743Smarkm    } else {
13444743Smarkm	return (daemon);
13544743Smarkm    }
13644743Smarkm}
137