Send a FQDN hostname if it contains dots, strip the domain from a looked up hostname if it matches our domain or search and sanitize our fd's a little better.

This commit is contained in:
Roy Marples 2007-04-26 16:16:56 +00:00
parent 6e9e8a1d4b
commit 0731074b52
11 changed files with 86 additions and 39 deletions

View File

@ -1,3 +1,4 @@
If the current hostname contains dots then send it as a FQDN.
Ensure that static routes are always added before routers.
Use getnameinfo instead of gethostbyaddr.
Remove gateways from the ROUTES and add to GATEWAYS

View File

@ -1,4 +1,4 @@
VERSION = 3.0.18_pre1
VERSION = 3.0.18_pre2
CFLAGS ?= -O2 -pipe
# Should work for both GNU make and BSD make

3
arp.c
View File

@ -51,6 +51,9 @@
(ap)->ar_hln + (ap)->ar_pln)
#define ar_tpa(ap) (((unsigned char *) ((ap) + 1)) + \
2 * (ap)->ar_hln + (ap)->ar_pln)
#endif
#ifndef arphdr_len
#define arphdr_len2(ar_hln, ar_pln) (sizeof (struct arphdr) + \
2 * (ar_hln) + 2 * (ar_pln))
#define arphdr_len(ap) (arphdr_len2 ((ap)->ar_hln, (ap)->ar_pln))

View File

@ -94,6 +94,7 @@
static int daemonise (const char *pidfile)
{
logger (LOG_DEBUG, "forking to background");
if (daemon (0, 0) < 0) {
logger (LOG_ERR, "daemon: %s", strerror (errno));
return -1;

View File

@ -104,6 +104,20 @@ void *xmalloc (size_t size)
return value;
logger (LOG_ERR, "memory exhausted");
exit (1);
exit (EXIT_FAILURE);
}
char *xstrdup (const char *str)
{
char *value;
if (! str)
return (NULL);
if ((value = strdup (str)))
return (value);
logger (LOG_ERR, "memory exhausted");
exit (EXIT_FAILURE);
}

View File

@ -34,6 +34,6 @@ size_t strlcpy (char *dst, const char *src, size_t size);
long uptime (void);
void *xmalloc (size_t size);
char *xstrdup (const char *str);
#endif

View File

@ -661,8 +661,8 @@ int configure (const options_t *options, interface_t *iface,
make_nis(iface->name, dhcp);
#endif
/* Now we have made a resolv.conf we can obtain a hostname if we need one */
if (options->dohostname && ! dhcp->hostname) {
/* Now we have made a resolv.conf we can obtain a hostname if we need it */
if (options->dohostname && ! dhcp->hostname) {
union {
struct sockaddr sa;
struct sockaddr_in sin;
@ -670,33 +670,55 @@ int configure (const options_t *options, interface_t *iface,
socklen_t salen;
char addr[NI_MAXHOST];
struct addrinfo hints, *res;
int result;
salen = sizeof (struct sockaddr);
memset (&su.sa, 0, salen);
su.sin.sin_family = AF_INET;
memcpy (&su.sin.sin_addr, &dhcp->address, sizeof (struct in_addr));
if (getnameinfo (&su.sa, salen, addr, sizeof (addr),
NULL, 0, NI_NAMEREQD) == 0) {
logger (LOG_DEBUG, "Looking up hostname via DNS");
if ((result = getnameinfo (&su.sa, salen, addr, sizeof (addr),
NULL, 0, NI_NAMEREQD)) != 0)
logger (LOG_ERR, "Failed to lookup hostname via DNS: %s", gai_strerror (result));
else {
/* Check for a malicious PTR record */
memset (&hints, 0, sizeof (hints));
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
/* Check for a malicious PTR record */
if (getaddrinfo (addr, "0", &hints, &res) == 0) {
freeaddrinfo (res);
addr[0] = '\0';
logger (LOG_ERR, "malicious PTR record detected");
} else if (*addr) {
/* Strip out the domain if it matches */
char *p = addr;
char *token = strsep (&p, ".");
bool match_domain = false;
if (p && *p) {
if (dhcp->dnssearch) {
char *s = xstrdup (dhcp->dnssearch);
char *sp = s;
char *t;
while ((t = strsep (&sp, " ")))
if (strcmp (t, p) == 0) {
match_domain = true;
break;
}
free (s);
} else if (dhcp->dnsdomain) {
if (strcmp (dhcp->dnsdomain, p) == 0)
match_domain = true;
}
}
if (match_domain)
strlcpy (newhostname, token, sizeof (newhostname));
else
snprintf (newhostname, sizeof (newhostname), "%s.%s", token, p);
}
}
/* Split the hostname from the domain */
if (addr[0]) {
char *p = addr;
char *token = strsep (&p, ".");
if (token)
strlcpy (newhostname, token, sizeof (newhostname));
} else
logger (LOG_ERR, "failed to lookup the hostname");
}
gethostname (curhostname, sizeof (curhostname));

View File

@ -109,6 +109,7 @@ int main(int argc, char **argv)
char prefix[IF_NAMESIZE + 3];
pid_t pid;
int debug = 0;
int i;
const struct option longopts[] = {
{"arp", no_argument, NULL, 'a'},
@ -137,13 +138,9 @@ int main(int argc, char **argv)
{NULL, 0, NULL, 0}
};
/* Sanitize our fd's */
int zero;
if ((zero = open (_PATH_DEVNULL, O_RDWR, 0)) >= 0) {
while (zero < 3)
zero = dup (zero);
close(zero);
}
/* Close any un-needed fd's */
for (i = getdtablesize() - 1; i >= 3; --i)
close (i);
openlog (PACKAGE, LOG_PID, LOG_LOCAL0);
@ -158,10 +155,6 @@ int main(int argc, char **argv)
options.dontp = true;
options.dogateway = true;
options.daemonise = true;
gethostname (options.hostname, sizeof (options.hostname));
if (strcmp (options.hostname, "(none)") == 0 ||
strcmp (options.hostname, "localhost") == 0)
memset (options.hostname, 0, sizeof (options.hostname));
options.timeout = DEFAULT_TIMEOUT;
while ((ch = getopt_long(argc, argv, "ac:dh:i:kl:m:nps:t:u:F:GHI:MNRY", longopts,
@ -242,7 +235,6 @@ int main(int argc, char **argv)
break;
case 'u':
{
int i;
int offset = 0;
for (i = 0; i < userclasses; i++)
offset += (int) options.userclass[offset] + 1;
@ -258,11 +250,11 @@ int main(int argc, char **argv)
}
break;
case 'F':
if (strcmp (optarg, "none") == 0)
if (strncmp (optarg, "none", strlen (optarg)) == 0)
options.fqdn = FQDN_NONE;
else if (strcmp (optarg, "ptr") == 0)
else if (strncmp (optarg, "ptr", strlen (optarg)) == 0)
options.fqdn = FQDN_PTR;
else if (strcmp (optarg, "both") == 0)
else if (strncmp (optarg, "both", strlen (optarg)) == 0)
options.fqdn = FQDN_BOTH;
else {
logger (LOG_ERR, "invalid value `%s' for FQDN", optarg);
@ -326,6 +318,19 @@ int main(int argc, char **argv)
exit (EXIT_FAILURE);
}
/* If we are given a hostname use it and set FQDN if it contains a . */
if (! options.hostname[0]) {
gethostname (options.hostname, sizeof (options.hostname));
if (strcmp (options.hostname, "(none)") == 0 ||
strcmp (options.hostname, "localhost") == 0)
memset (options.hostname, 0, sizeof (options.hostname));
}
if (strchr (options.hostname, '.')) {
if (options.fqdn == FQDN_DISABLE)
options.fqdn = FQDN_BOTH;
} else
options.fqdn = FQDN_DISABLE;
if (geteuid ()) {
logger (LOG_ERR, "you need to be root to run "PACKAGE);
exit (EXIT_FAILURE);

View File

@ -407,7 +407,7 @@ static int do_route (const char *ifname,
/* Do something with metric to satisfy compiler warnings */
metric = 0;
dstd = strdup (inet_ntoa (destination));
dstd = xstrdup (inet_ntoa (destination));
if (gateway.s_addr == destination.s_addr)
logger (LOG_INFO, "%s route to %s/%d",
change ? "changing" : del ? "removing" : "adding",
@ -738,8 +738,8 @@ static int do_route (const char *ifname,
if (! ifname)
return -1;
dstd = strdup (inet_ntoa (destination));
gend = strdup (inet_ntoa (netmask));
dstd = xstrdup (inet_ntoa (destination));
gend = xstrdup (inet_ntoa (netmask));
if (gateway.s_addr == destination.s_addr)
logger (LOG_INFO, "%s route to %s (%s) metric %d",
change ? "changing" : del ? "removing" : "adding",

View File

@ -91,6 +91,10 @@ void logger(int level, const char *fmt, ...)
fprintf (f, "%s, %s", syslog_level_msg[level], logprefix);
vfprintf (f, fmt, p);
fputc ('\n', f);
/* stdout, stderr may be re-directed to some kind of buffer.
* So we always flush to ensure it's written. */
fflush (f);
}
if (level < LOG_DEBUG || level <= loglevel) {

View File

@ -24,6 +24,7 @@
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#ifndef __OpenBSD__
@ -32,10 +33,6 @@
#include <net/ethernet.h>
#endif
#include <netinet/udp.h>
#ifndef __linux__
#include <net/if_types.h>
#endif
#include <net/if.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>