X-Git-Url: https://git.decadent.org.uk/gitweb/?a=blobdiff_plain;ds=sidebyside;f=utils%2Fmountd%2Fauth.c;h=6b6b7d74cf4fb1afe788b5055e303dde627f54a8;hb=75cbc5abeb4b1d39abf298be217783c2b0889ae5;hp=9f63120b8b58b5677bcfd99060ed6081a9377222;hpb=8b7ad01b14df1e7529b9ba8a1ea17df0d6004ef9;p=nfs-utils.git diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c index 9f63120..6b6b7d7 100644 --- a/utils/mountd/auth.c +++ b/utils/mountd/auth.c @@ -16,6 +16,7 @@ #include "nfslib.h" #include "exportfs.h" #include "mountd.h" +#include "xmalloc.h" enum auth_error { @@ -25,6 +26,7 @@ enum auth_error not_exported, illegal_port, faked_hostent, + no_forward_dns, success }; @@ -76,35 +78,59 @@ auth_authenticate_internal(char *what, struct sockaddr_in *caller, } auth_fixpath(path); - if (!(*hpp = gethostbyaddr((const char *)&addr, sizeof(addr), AF_INET))) - *hpp = get_hostent((const char *)&addr, sizeof(addr), - AF_INET); - else { + /* First try it w/o doing a hostname lookup... */ + *hpp = get_hostent((const char *)&addr, sizeof(addr), AF_INET); + exp = export_find(*hpp, path); + + if (!exp) { + /* Ok, that didn't fly. Try it with a reverse lookup. */ + free (*hpp); + *hpp = gethostbyaddr((const char *)&addr, sizeof(addr), + AF_INET); + if (!(*hpp)) { + *error = no_entry; + *hpp = get_hostent((const char *)&addr, sizeof(addr), AF_INET); + return NULL; + } else { /* must make sure the hostent is authorative. */ - char *name = strdup((*hpp)->h_name); char **sp; - *hpp = gethostbyname(name); - /* now make sure the "addr" is in the list */ - for (sp = (*hpp)->h_addr_list ; *sp ; sp++) { - if (memcmp(*sp, &addr, (*hpp)->h_length)==0) - break; + struct hostent *forward = NULL; + char *tmpname; + + *hpp = hostent_dup (*hpp); + tmpname = xstrdup((*hpp)->h_name); + if (tmpname) { + forward = gethostbyname(tmpname); + free(tmpname); } + if (forward) { + /* now make sure the "addr" is in the list */ + for (sp = forward->h_addr_list ; *sp ; sp++) { + if (memcmp(*sp, &addr, forward->h_length)==0) + break; + } - if (!*sp) { - free(name); - /* it was a FAKE */ - *error = faked_hostent; - *hpp = NULL; + if (!*sp) { + /* it was a FAKE */ + *error = faked_hostent; + return NULL; + } + free (*hpp); + *hpp = hostent_dup (forward); + } + else { + /* never heard of it. misconfigured DNS? */ + *error = no_forward_dns; return NULL; } - *hpp = hostent_dup (*hpp); - free(name); - } + } - if (!(exp = export_find(*hpp, path))) { + if (!(exp = export_find(*hpp, path))) { *error = no_entry; return NULL; + } } + if (!exp->m_mayexport) { *error = not_exported; return NULL; @@ -132,7 +158,11 @@ auth_authenticate(char *what, struct sockaddr_in *caller, char *path) struct in_addr addr = caller->sin_addr; enum auth_error error; - if (path [0] != '/') return exp; + if (path [0] != '/') { + xlog(L_WARNING, "bad path in %s request from %s: \"%s\"", + what, inet_ntoa(addr), path); + return exp; + } strncpy(epath, path, sizeof (epath) - 1); epath[sizeof (epath) - 1] = '\0'; @@ -181,8 +211,13 @@ auth_authenticate(char *what, struct sockaddr_in *caller, char *path) break; case faked_hostent: - xlog(L_WARNING, "refused %s request from %s for %s (%s): faked hostent", - what, inet_ntoa(addr), path, epath); + xlog(L_WARNING, "refused %s request from %s (%s) for %s (%s): DNS forward lookup does't match with reverse", + what, inet_ntoa(addr), hp->h_name, path, epath); + break; + + case no_forward_dns: + xlog(L_WARNING, "refused %s request from %s (%s) for %s (%s): no DNS forward lookup", + what, inet_ntoa(addr), hp->h_name, path, epath); break; case success: