@@ -52,4 +52,6 @@ int gssd_check_mechs(void);
gss_krb5_set_allowable_enctypes(min, cred, num, types)
#endif
+extern int avoid_dns;
+
#endif /* _GSS_UTIL_H_ */
@@ -85,7 +85,7 @@ sig_hup(int signal)
static void
usage(char *progname)
{
- fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm]\n",
+ fprintf(stderr, "usage: %s [-f] [-l] [-M] [-n] [-v] [-r] [-p pipefsdir] [-k keytab] [-d ccachedir] [-t timeout] [-R preferred realm] [-D]\n",
progname);
exit(1);
}
@@ -102,7 +102,7 @@ main(int argc, char *argv[])
char *progname;
memset(ccachesearch, 0, sizeof(ccachesearch));
- while ((opt = getopt(argc, argv, "fvrlmnMp:k:d:t:R:")) != -1) {
+ while ((opt = getopt(argc, argv, "DfvrlmnMp:k:d:t:R:")) != -1) {
switch (opt) {
case 'f':
fg = 1;
@@ -150,6 +150,9 @@ main(int argc, char *argv[])
errx(1, "Encryption type limits not supported by Kerberos libraries.");
#endif
break;
+ case 'D':
+ avoid_dns = 0;
+ break;
default:
usage(argv[0]);
break;
@@ -8,7 +8,7 @@
rpc.gssd \- RPCSEC_GSS daemon
.SH SYNOPSIS
.B rpc.gssd
-.RB [ \-fMnlvr ]
+.RB [ \-DfMnlvr ]
.RB [ \-k
.IR keytab ]
.RB [ \-p
@@ -195,6 +195,12 @@ option when starting
.BR rpc.gssd .
.SH OPTIONS
.TP
+.B -D
+DNS Reverse lookups are not used for determining the
+server names pass to GSSAPI. This option will reverses that and forces
+the use of DNS Reverse resolution of the server's IP address to
+retrieve the server name to use in GSAPI authentication.
+.TP
.B -f
Runs
.B rpc.gssd
@@ -67,6 +67,7 @@
#include <errno.h>
#include <gssapi/gssapi.h>
#include <netdb.h>
+#include <ctype.h>
#include "gssd.h"
#include "err_util.h"
@@ -107,6 +108,9 @@ struct pollfd * pollarray;
unsigned long pollsize; /* the size of pollaray (in pollfd's) */
+/* Avoid DNS reverse lookups on server names */
+int avoid_dns = 1;
+
/*
* convert a presentation address string to a sockaddr_storage struct. Returns
* true on success or false on failure.
@@ -165,12 +169,31 @@ addrstr_to_sockaddr(struct sockaddr *sa, const char *node, const char *port)
* convert a sockaddr to a hostname
*/
static char *
-sockaddr_to_hostname(const struct sockaddr *sa, const char *addr)
+get_servername(const char *name, const struct sockaddr *sa, const char *addr)
{
socklen_t addrlen;
int err;
char *hostname;
char hbuf[NI_MAXHOST];
+ unsigned char buf[sizeof(struct in6_addr)];
+ int servername = 0;
+
+ if (avoid_dns) {
+ /*
+ * Determine if this is a server name, or an IP address.
+ * If it is an IP address, do the DNS lookup otherwise
+ * skip the DNS lookup.
+ */
+ servername = 0;
+ if (strchr(name, '.') && inet_pton(AF_INET, name, buf) == 1)
+ servername = 1; /* IPv4 */
+ else if (strchr(name, ':') && inet_pton(AF_INET6, name, buf) == 1)
+ servername = 1; /* or IPv6 */
+
+ if (servername) {
+ return strdup(name);
+ }
+ }
switch (sa->sa_family) {
case AF_INET:
@@ -208,7 +231,7 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
struct sockaddr *addr) {
#define INFOBUFLEN 256
char buf[INFOBUFLEN + 1];
- static char dummy[128];
+ static char server[128];
int nbytes;
static char service[128];
static char address[128];
@@ -236,7 +259,7 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
"service: %127s %15s version %15s\n"
"address: %127s\n"
"protocol: %15s\n",
- dummy,
+ server,
service, program, version,
address,
protoname);
@@ -258,7 +281,7 @@ read_service_info(char *info_file_name, char **servicename, char **servername,
if (!addrstr_to_sockaddr(addr, address, port))
goto fail;
- *servername = sockaddr_to_hostname(addr, address);
+ *servername = get_servername(server, addr, address);
if (*servername == NULL)
goto fail;