]> git.decadent.org.uk Git - nfs-utils.git/commitdiff
Avoid DNS reverse resolution for server names (take 3)
authorSimo Sorce <simo@redhat.com>
Fri, 19 Apr 2013 14:10:33 +0000 (10:10 -0400)
committerSteve Dickson <steved@redhat.com>
Mon, 22 Apr 2013 16:47:20 +0000 (12:47 -0400)
A NFS client should be able to work properly even if the DNS Reverse
record for the server is not set. This means a DNS lookup should not be
done on server names at are passed to GSSAPI. This patch changes the default
behavior to no longer do those types of lookups

This change default behavior could negatively impact some current
environments, so the -D option is also being added that will re-enable
the DNS reverse looks on server names, which are passed to GSSAPI.

Signed-off-by: Simo Sorce <simo@redhat.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
utils/gssd/gss_util.h
utils/gssd/gssd.c
utils/gssd/gssd.man
utils/gssd/gssd_proc.c

index aa9f77806075f9ab67a7763a75a010369ba2d1b9..c81fc5a98d5fbe0864b1c1b172e3cd5c28ed6800 100644 (file)
@@ -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_ */
index 07b1e52e6b84e9bcba96e7a63b0505ca7823482a..8ee478bc0bccb0aedee7bd3557e0f194ad69ab30 100644 (file)
@@ -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;
index 79d9bf91ac6b976c57d167e60d07f828a3ff5b1f..1df75c57e1f6f09fb5a2891a4554751583b5cf1c 100644 (file)
@@ -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
index 22800885e2be12ce9fdc68386c63025fde68ca21..af1844c2d38490e1ccb5c21e2aa45cd34cca376e 100644 (file)
@@ -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;