]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - support/export/client.c
call gethostbyaddr to make sure that we have canonical hostname
[nfs-utils.git] / support / export / client.c
index 8c5200af10ef36aba828ca74d89f9d7a8ba88dd7..076b0c069dd1ff2991d374ee8c498087601321e8 100644 (file)
@@ -42,12 +42,22 @@ client_lookup(char *hname)
        htype = client_gettype(hname);
 
        if (htype == MCL_FQDN) {
+               struct hostent *hp2;
                hp = gethostbyname(hname);
                if (hp == NULL || hp->h_addrtype != AF_INET) {
                        xlog(L_ERROR, "%s has non-inet addr", hname);
                        return NULL;
                }
-               hp = hostent_dup (hp);
+               /* make sure we have canonical name */
+               hp2 = hostent_dup(hp);
+               hp = gethostbyaddr(hp2->h_addr, hp2->h_length,
+                                  hp2->h_addrtype);
+               if (hp) {
+                       free(hp2);
+                       hp = hostent_dup(hp);
+               } else
+                       hp = hp2;
+
                hname = (char *) hp->h_name;
 
                for (clp = clientlist[htype]; clp; clp = clp->m_next) {
@@ -118,7 +128,20 @@ client_init(nfs_client *clp, const char *hname, struct hostent *hp)
 
                *cp = '\0';
                clp->m_addrlist[0].s_addr = inet_addr(clp->m_hostname);
-               clp->m_addrlist[1].s_addr = inet_addr(cp+1);
+               if (strchr(cp + 1, '.')) {
+                       clp->m_addrlist[1].s_addr = inet_addr(cp+1);
+               }
+               else {
+                       int netmask = atoi(cp + 1);
+                       if (0 < netmask && netmask <= 32) {
+                               clp->m_addrlist[1].s_addr =
+                                       htonl ((uint32_t) ~0 << (32 - netmask));
+                       }
+                       else {
+                               xlog(L_FATAL, "invalid netmask `%s' for %s",
+                                    cp + 1, clp->m_hostname);
+                       }
+               }
                *cp = '/';
                clp->m_naddr = 0;
        } else if (!hp) {
@@ -226,18 +249,29 @@ client_check(nfs_client *clp, struct hostent *hp)
                {
                        char    *dot;
                        int     match;
+                       struct hostent *nhp = NULL;
+                       struct sockaddr_in addr;
 
                        /* First, try to match the hostname without
                         * splitting off the domain */
                        if (innetgr(cname+1, hname, NULL, NULL))
                                return 1;
 
+                       /* If hname is ip address convert to FQDN */
+                       if (inet_aton(hname, &addr.sin_addr) &&
+                          (nhp = gethostbyaddr((const char *)&(addr.sin_addr),
+                           sizeof(addr.sin_addr), AF_INET))) {
+                               hname = (char *)nhp->h_name;
+                               if (innetgr(cname+1, hname, NULL, NULL))
+                                       return 1;
+                       }
+
                        /* Okay, strip off the domain (if we have one) */
                        if ((dot = strchr(hname, '.')) == NULL)
                                return 0;
 
                        *dot = '\0';
-                       match = innetgr(cname+1, hname, NULL, dot + 1);
+                       match = innetgr(cname+1, hname, NULL, NULL);
                        *dot = '.';
 
                        return match;
@@ -278,7 +312,7 @@ client_gettype(char *ident)
 {
        char    *sp;
 
-       if (ident[0] == '\0')
+       if (ident[0] == '\0' || strcmp(ident, "*")==0)
                return MCL_ANONYMOUS;
        if (ident[0] == '@') {
 #ifndef HAVE_INNETGR