nfs_client *clientlist[MCL_MAXTYPES] = { NULL, };
+/* if canonical is set, then we *know* this is already a canonical name
+ * so hostname lookup is avoided.
+ * This is used when reading /proc/fs/nfs/exports
+ */
nfs_client *
-client_lookup(char *hname)
+client_lookup(char *hname, int canonical)
{
nfs_client *clp = NULL;
int htype;
htype = client_gettype(hname);
- if (htype == MCL_FQDN) {
+ if (htype == MCL_FQDN && !canonical) {
+ 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) {
+ hp = hostent_dup(hp);
+ /* but now we might not have all addresses... */
+ if (hp2->h_addr_list[1]) {
+ struct hostent *hp3 =
+ gethostbyname(hp->h_name);
+ if (hp3) {
+ free(hp);
+ hp = hostent_dup(hp3);
+ }
+ }
+ free(hp2);
+ } else
+ hp = hp2;
+
hname = (char *) hp->h_name;
for (clp = clientlist[htype]; clp; clp = clp->m_next) {
}
} else {
for (clp = clientlist[htype]; clp; clp = clp->m_next) {
- if (strcmp(hname, clp->m_hostname)==0)
+ if (strcasecmp(hname, clp->m_hostname)==0)
break;
}
}
*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) {
{
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;
{
char *sp;
- if (ident[0] == '\0')
+ if (ident[0] == '\0' || strcmp(ident, "*")==0)
return MCL_ANONYMOUS;
if (ident[0] == '@') {
#ifndef HAVE_INNETGR