Changeset View
Changeset View
Standalone View
Standalone View
contrib/tcp_wrappers/hosts_access.c
Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | |||||
/* definition to be used from workarounds.c */ | /* definition to be used from workarounds.c */ | ||||
#ifdef NETGROUP | #ifdef NETGROUP | ||||
int yp_get_default_domain(char **); | int yp_get_default_domain(char **); | ||||
#endif | #endif | ||||
/* hosts_access - host access control facility */ | /* hosts_access - host access control facility */ | ||||
int hosts_access(request) | int hosts_access(struct request_info *request) | ||||
struct request_info *request; | |||||
{ | { | ||||
int verdict; | int verdict; | ||||
/* | /* | ||||
* If the (daemon, client) pair is matched by an entry in the file | * If the (daemon, client) pair is matched by an entry in the file | ||||
* /etc/hosts.allow, access is granted. Otherwise, if the (daemon, | * /etc/hosts.allow, access is granted. Otherwise, if the (daemon, | ||||
* client) pair is matched by an entry in the file /etc/hosts.deny, | * client) pair is matched by an entry in the file /etc/hosts.deny, | ||||
* access is denied. Otherwise, access is granted. A non-existent | * access is denied. Otherwise, access is granted. A non-existent | ||||
Show All 16 Lines | int hosts_access(struct request_info *request) | ||||
return (YES); | return (YES); | ||||
if (table_match(hosts_deny_table, request)) | if (table_match(hosts_deny_table, request)) | ||||
return (NO); | return (NO); | ||||
return (YES); | return (YES); | ||||
} | } | ||||
/* table_match - match table entries with (daemon, client) pair */ | /* table_match - match table entries with (daemon, client) pair */ | ||||
static int table_match(table, request) | static int table_match(char *table, struct request_info *request) | ||||
char *table; | |||||
struct request_info *request; | |||||
{ | { | ||||
FILE *fp; | FILE *fp; | ||||
char sv_list[BUFLEN]; /* becomes list of daemons */ | char sv_list[BUFLEN]; /* becomes list of daemons */ | ||||
char *cl_list; /* becomes list of clients */ | char *cl_list; /* becomes list of clients */ | ||||
char *sh_cmd; /* becomes optional shell command */ | char *sh_cmd; /* becomes optional shell command */ | ||||
int match = NO; | int match = NO; | ||||
struct tcpd_context saved_context; | struct tcpd_context saved_context; | ||||
char *cp; | char *cp; | ||||
▲ Show 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | /* VOID */ ; | ||||
return (tok == 0 || list_match((char *) 0, request, match_fn) == 0); | return (tok == 0 || list_match((char *) 0, request, match_fn) == 0); | ||||
} | } | ||||
} | } | ||||
return (NO); | return (NO); | ||||
} | } | ||||
/* server_match - match server information */ | /* server_match - match server information */ | ||||
static int server_match(tok, request) | static int server_match(char *tok, struct request_info *request) | ||||
char *tok; | |||||
struct request_info *request; | |||||
{ | { | ||||
char *host; | char *host; | ||||
if ((host = split_at(tok + 1, '@')) == 0) { /* plain daemon */ | if ((host = split_at(tok + 1, '@')) == 0) { /* plain daemon */ | ||||
return (string_match(tok, eval_daemon(request))); | return (string_match(tok, eval_daemon(request))); | ||||
} else { /* daemon@host */ | } else { /* daemon@host */ | ||||
return (string_match(tok, eval_daemon(request)) | return (string_match(tok, eval_daemon(request)) | ||||
&& host_match(host, request->server)); | && host_match(host, request->server)); | ||||
} | } | ||||
} | } | ||||
/* client_match - match client information */ | /* client_match - match client information */ | ||||
static int client_match(tok, request) | static int client_match(char *tok, struct request_info *request) | ||||
char *tok; | |||||
struct request_info *request; | |||||
{ | { | ||||
char *host; | char *host; | ||||
if ((host = split_at(tok + 1, '@')) == 0) { /* plain host */ | if ((host = split_at(tok + 1, '@')) == 0) { /* plain host */ | ||||
return (host_match(tok, request->client)); | return (host_match(tok, request->client)); | ||||
} else { /* user@host */ | } else { /* user@host */ | ||||
return (host_match(host, request->client) | return (host_match(host, request->client) | ||||
&& string_match(tok, eval_user(request))); | && string_match(tok, eval_user(request))); | ||||
} | } | ||||
} | } | ||||
/* hostfile_match - look up host patterns from file */ | /* hostfile_match - look up host patterns from file */ | ||||
static int hostfile_match(path, host) | static int hostfile_match(char *path, struct host_info *host) | ||||
char *path; | |||||
struct host_info *host; | |||||
{ | { | ||||
char tok[BUFSIZ]; | char tok[BUFSIZ]; | ||||
int match = NO; | int match = NO; | ||||
FILE *fp; | FILE *fp; | ||||
if ((fp = fopen(path, "r")) != 0) { | if ((fp = fopen(path, "r")) != 0) { | ||||
while (fscanf(fp, "%s", tok) == 1 && !(match = host_match(tok, host))) | while (fscanf(fp, "%s", tok) == 1 && !(match = host_match(tok, host))) | ||||
/* void */ ; | /* void */ ; | ||||
fclose(fp); | fclose(fp); | ||||
} else if (errno != ENOENT) { | } else if (errno != ENOENT) { | ||||
tcpd_warn("open %s: %m", path); | tcpd_warn("open %s: %m", path); | ||||
} | } | ||||
return (match); | return (match); | ||||
} | } | ||||
/* host_match - match host name and/or address against pattern */ | /* host_match - match host name and/or address against pattern */ | ||||
static int host_match(tok, host) | static int host_match(char *tok, struct host_info *host) | ||||
char *tok; | |||||
struct host_info *host; | |||||
{ | { | ||||
char *mask; | char *mask; | ||||
/* | /* | ||||
* This code looks a little hairy because we want to avoid unnecessary | * This code looks a little hairy because we want to avoid unnecessary | ||||
* hostname lookups. | * hostname lookups. | ||||
* | * | ||||
* The KNOWN pattern requires that both address AND name be known; some | * The KNOWN pattern requires that both address AND name be known; some | ||||
Show All 24 Lines | return (masked_match(tok, mask, eval_hostaddr(host))); | ||||
} else { /* anything else */ | } else { /* anything else */ | ||||
return (string_match(tok, eval_hostaddr(host)) | return (string_match(tok, eval_hostaddr(host)) | ||||
|| (NOT_INADDR(tok) && string_match(tok, eval_hostname(host)))); | || (NOT_INADDR(tok) && string_match(tok, eval_hostname(host)))); | ||||
} | } | ||||
} | } | ||||
/* string_match - match string against pattern */ | /* string_match - match string against pattern */ | ||||
static int string_match(tok, string) | static int string_match(char *tok, char *string) | ||||
char *tok; | |||||
char *string; | |||||
{ | { | ||||
int n; | int n; | ||||
#ifdef INET6 | #ifdef INET6 | ||||
/* convert IPv4 mapped IPv6 address to IPv4 address */ | /* convert IPv4 mapped IPv6 address to IPv4 address */ | ||||
if (STRN_EQ(string, "::ffff:", 7) | if (STRN_EQ(string, "::ffff:", 7) | ||||
&& dot_quad_addr(string + 7) != INADDR_NONE) { | && dot_quad_addr(string + 7) != INADDR_NONE) { | ||||
string += 7; | string += 7; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
return (STR_EQ(tok, string)); | return (STR_EQ(tok, string)); | ||||
} | } | ||||
} | } | ||||
/* masked_match - match address against netnumber/netmask */ | /* masked_match - match address against netnumber/netmask */ | ||||
#ifdef INET6 | #ifdef INET6 | ||||
static int masked_match(net_tok, mask_tok, string) | static int masked_match(char *net_tok, char *mask_tok, char *string) | ||||
char *net_tok; | |||||
char *mask_tok; | |||||
char *string; | |||||
{ | { | ||||
return (masked_match4(net_tok, mask_tok, string) || | return (masked_match4(net_tok, mask_tok, string) || | ||||
masked_match6(net_tok, mask_tok, string)); | masked_match6(net_tok, mask_tok, string)); | ||||
} | } | ||||
static int masked_match4(net_tok, mask_tok, string) | static int masked_match4(char *net_tok, char *mask_tok, char *string) | ||||
#else | #else | ||||
static int masked_match(net_tok, mask_tok, string) | static int masked_match(char *net_tok, char *mask_tok, char *string) | ||||
#endif | #endif | ||||
char *net_tok; | |||||
char *mask_tok; | |||||
char *string; | |||||
{ | { | ||||
#ifdef INET6 | #ifdef INET6 | ||||
u_int32_t net; | u_int32_t net; | ||||
u_int32_t mask; | u_int32_t mask; | ||||
u_int32_t addr; | u_int32_t addr; | ||||
#else | #else | ||||
unsigned long net; | unsigned long net; | ||||
unsigned long mask; | unsigned long mask; | ||||
Show All 14 Lines | #ifndef INET6 | ||||
tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok); | tcpd_warn("bad net/mask expression: %s/%s", net_tok, mask_tok); | ||||
#endif | #endif | ||||
return (NO); /* not tcpd_jump() */ | return (NO); /* not tcpd_jump() */ | ||||
} | } | ||||
return ((addr & mask) == net); | return ((addr & mask) == net); | ||||
} | } | ||||
#ifdef INET6 | #ifdef INET6 | ||||
static int masked_match6(net_tok, mask_tok, string) | static int masked_match6(char *net_tok, char *mask_tok, char *string) | ||||
char *net_tok; | |||||
char *mask_tok; | |||||
char *string; | |||||
{ | { | ||||
struct addrinfo hints, *res; | struct addrinfo hints, *res; | ||||
struct sockaddr_in6 net, addr; | struct sockaddr_in6 net, addr; | ||||
u_int32_t mask; | u_int32_t mask; | ||||
int len, mask_len, i = 0; | int len, mask_len, i = 0; | ||||
char ch; | char ch; | ||||
memset(&hints, 0, sizeof(hints)); | memset(&hints, 0, sizeof(hints)); | ||||
▲ Show 20 Lines • Show All 48 Lines • Show Last 20 Lines |