summaryrefslogtreecommitdiffstats
path: root/utils/mountd
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2010-06-22 12:43:01 -0400
committerSteve Dickson <steved@redhat.com>2010-06-22 16:04:53 -0400
commit0509d3428f523776ddd9d6e9fa318587d3ec7d84 (patch)
treef8f3cb4d1af6f60bc178800790b666a63c323b61 /utils/mountd
parent3ca5879be32c4c11750e12230ff588195fff0738 (diff)
downloadnfs-utils-0509d3428f523776ddd9d6e9fa318587d3ec7d84.tar.gz
nfs-utils-0509d3428f523776ddd9d6e9fa318587d3ec7d84.tar.xz
nfs-utils-0509d3428f523776ddd9d6e9fa318587d3ec7d84.zip
mountd: Replace "struct hostent" with "struct addrinfo"
struct hostent can store either IPv4 or IPv6 addresses, but it can't store both address families concurrently for the same host. Neither can hostent deal with parts of socket addresses that are outside of the sin{,6}_addr field. Replace the use of "struct hostent" everywhere in libexport.a, mountd, and exportfs with "struct addrinfo". This is a large change, but there are so many strong dependencies on struct hostent that this can't easily be broken into smaller pieces. One benefit of this change is that hostent_dup() is no longer required, since the results of getaddrinfo(3) are already dynamically allocated. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Steve Dickson <steved@redhat.com>
Diffstat (limited to 'utils/mountd')
-rw-r--r--utils/mountd/auth.c48
-rw-r--r--utils/mountd/cache.c66
-rw-r--r--utils/mountd/mountd.c11
3 files changed, 67 insertions, 58 deletions
diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c
index 4b94b98..04487e5 100644
--- a/utils/mountd/auth.c
+++ b/utils/mountd/auth.c
@@ -110,13 +110,15 @@ auth_reload()
return counter;
}
-static char *get_client_hostname(struct sockaddr_in *caller, struct hostent *hp, enum auth_error *error)
+static char *
+get_client_hostname(struct sockaddr_in *caller, struct addrinfo *ai,
+ enum auth_error *error)
{
char *n;
if (use_ipaddr)
return strdup(inet_ntoa(caller->sin_addr));
- n = client_compose(hp);
+ n = client_compose(ai);
*error = unknown_host;
if (!n)
return NULL;
@@ -128,8 +130,8 @@ static char *get_client_hostname(struct sockaddr_in *caller, struct hostent *hp,
/* return static nfs_export with details filled in */
static nfs_export *
-auth_authenticate_newcache(char *what, struct sockaddr_in *caller,
- char *path, struct hostent *hp,
+auth_authenticate_newcache(struct sockaddr_in *caller,
+ char *path, struct addrinfo *ai,
enum auth_error *error)
{
nfs_export *exp;
@@ -137,7 +139,7 @@ auth_authenticate_newcache(char *what, struct sockaddr_in *caller,
free(my_client.m_hostname);
- my_client.m_hostname = get_client_hostname(caller, hp, error);
+ my_client.m_hostname = get_client_hostname(caller, ai, error);
if (my_client.m_hostname == NULL)
return NULL;
@@ -152,7 +154,7 @@ auth_authenticate_newcache(char *what, struct sockaddr_in *caller,
continue;
if (!use_ipaddr && !client_member(my_client.m_hostname, exp->m_client->m_hostname))
continue;
- if (use_ipaddr && !client_check(exp->m_client, hp))
+ if (use_ipaddr && !client_check(exp->m_client, ai))
continue;
break;
}
@@ -166,18 +168,19 @@ auth_authenticate_newcache(char *what, struct sockaddr_in *caller,
}
static nfs_export *
-auth_authenticate_internal(char *what, struct sockaddr_in *caller,
- char *path, struct hostent *hp,
+auth_authenticate_internal(struct sockaddr_in *caller,
+ char *path, struct addrinfo *ai,
enum auth_error *error)
{
nfs_export *exp;
if (new_cache) {
- exp = auth_authenticate_newcache(what, caller, path, hp, error);
+ exp = auth_authenticate_newcache(caller, path, ai, error);
if (!exp)
return NULL;
} else {
- if (!(exp = export_find(hp, path))) {
+ exp = export_find(ai, path);
+ if (exp == NULL) {
*error = no_entry;
return NULL;
}
@@ -202,7 +205,7 @@ auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
nfs_export *exp = NULL;
char epath[MAXPATHLEN+1];
char *p = NULL;
- struct hostent *hp = NULL;
+ struct addrinfo *ai = NULL;
struct in_addr addr = caller->sin_addr;
enum auth_error error = bad_path;
@@ -216,14 +219,14 @@ auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
epath[sizeof (epath) - 1] = '\0';
auth_fixpath(epath); /* strip duplicate '/' etc */
- hp = client_resolve(caller->sin_addr);
- if (!hp)
+ ai = client_resolve((struct sockaddr *)caller);
+ if (ai == NULL)
return exp;
/* Try the longest matching exported pathname. */
while (1) {
- exp = auth_authenticate_internal(what, caller, epath,
- hp, &error);
+ exp = auth_authenticate_internal(caller, epath,
+ ai, &error);
if (exp || (error != not_exported && error != no_entry))
break;
/* We have to treat the root, "/", specially. */
@@ -246,31 +249,30 @@ auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
case no_entry:
xlog(L_WARNING, "refused %s request from %s for %s (%s): no export entry",
- what, hp->h_name, path, epath);
+ what, ai->ai_canonname, path, epath);
break;
case not_exported:
xlog(L_WARNING, "refused %s request from %s for %s (%s): not exported",
- what, hp->h_name, path, epath);
+ what, ai->ai_canonname, path, epath);
break;
case illegal_port:
xlog(L_WARNING, "refused %s request from %s for %s (%s): illegal port %d",
- what, hp->h_name, path, epath, ntohs(caller->sin_port));
+ what, ai->ai_canonname, path, epath, ntohs(caller->sin_port));
break;
case success:
xlog(L_NOTICE, "authenticated %s request from %s:%d for %s (%s)",
- what, hp->h_name, ntohs(caller->sin_port), path, epath);
+ what, ai->ai_canonname, ntohs(caller->sin_port), path, epath);
break;
default:
xlog(L_NOTICE, "%s request from %s:%d for %s (%s) gave %d",
- what, hp->h_name, ntohs(caller->sin_port), path, epath, error);
+ what, ai->ai_canonname, ntohs(caller->sin_port),
+ path, epath, error);
}
- if (hp)
- free (hp);
-
+ freeaddrinfo(ai);
return exp;
}
diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index 1176c62..9e1b164 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -77,8 +77,8 @@ void auth_unix_ip(FILE *f)
char class[20];
char ipaddr[20];
char *client = NULL;
- struct in_addr addr;
- struct hostent *he = NULL;
+ struct addrinfo *tmp = NULL;
+ struct addrinfo *ai = NULL;
if (readline(fileno(f), &lbuf, &lbuflen) != 1)
return;
@@ -93,17 +93,20 @@ void auth_unix_ip(FILE *f)
if (qword_get(&cp, ipaddr, 20) <= 0)
return;
- if (inet_aton(ipaddr, &addr)==0)
+ tmp = host_pton(ipaddr);
+ if (tmp == NULL)
return;
auth_reload();
/* addr is a valid, interesting address, find the domain name... */
if (!use_ipaddr) {
- he = client_resolve(addr);
- client = client_compose(he);
+ ai = client_resolve(tmp->ai_addr);
+ client = client_compose(ai);
+ freeaddrinfo(ai);
}
-
+ freeaddrinfo(tmp);
+
qword_print(f, "nfsd");
qword_print(f, ipaddr);
qword_printint(f, time(0)+30*60);
@@ -114,8 +117,7 @@ void auth_unix_ip(FILE *f)
qword_eol(f);
xlog(D_CALL, "auth_unix_ip: client %p '%s'", client, client?client: "DEFAULT");
- if (client) free(client);
- free(he);
+ free(client);
}
void auth_unix_gid(FILE *f)
@@ -338,8 +340,7 @@ void nfsd_fh(FILE *f)
unsigned int fsidnum=0;
char fsid[32];
struct exportent *found = NULL;
- struct hostent *he = NULL;
- struct in_addr addr;
+ struct addrinfo *ai = NULL;
char *found_path = NULL;
nfs_export *exp;
int i;
@@ -520,12 +521,15 @@ void nfsd_fh(FILE *f)
break;
}
if (use_ipaddr) {
- if (he == NULL) {
- if (!inet_aton(dom, &addr))
+ if (ai == NULL) {
+ struct addrinfo *tmp;
+ tmp = host_pton(dom);
+ if (tmp == NULL)
goto out;
- he = client_resolve(addr);
+ ai = client_resolve(tmp->ai_addr);
+ freeaddrinfo(tmp);
}
- if (!client_check(exp->m_client, he))
+ if (!client_check(exp->m_client, ai))
continue;
}
/* It's a match !! */
@@ -583,8 +587,7 @@ void nfsd_fh(FILE *f)
out:
if (found_path)
free(found_path);
- if (he)
- free(he);
+ freeaddrinfo(ai);
free(dom);
xlog(D_CALL, "nfsd_fh: found %p path %s", found, found ? found->e_path : NULL);
return;
@@ -678,19 +681,22 @@ static int path_matches(nfs_export *exp, char *path)
return strcmp(path, exp->m_export.e_path) == 0;
}
-static int client_matches(nfs_export *exp, char *dom, struct hostent *he)
+static int
+client_matches(nfs_export *exp, char *dom, struct addrinfo *ai)
{
if (use_ipaddr)
- return client_check(exp->m_client, he);
+ return client_check(exp->m_client, ai);
return client_member(dom, exp->m_client->m_hostname);
}
-static int export_matches(nfs_export *exp, char *dom, char *path, struct hostent *he)
+static int
+export_matches(nfs_export *exp, char *dom, char *path, struct addrinfo *ai)
{
- return path_matches(exp, path) && client_matches(exp, dom, he);
+ return path_matches(exp, path) && client_matches(exp, dom, ai);
}
-static nfs_export *lookup_export(char *dom, char *path, struct hostent *he)
+static nfs_export *
+lookup_export(char *dom, char *path, struct addrinfo *ai)
{
nfs_export *exp;
nfs_export *found = NULL;
@@ -699,7 +705,7 @@ static nfs_export *lookup_export(char *dom, char *path, struct hostent *he)
for (i=0 ; i < MCL_MAXTYPES; i++) {
for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
- if (!export_matches(exp, dom, path, he))
+ if (!export_matches(exp, dom, path, ai))
continue;
if (!found) {
found = exp;
@@ -747,9 +753,7 @@ void nfsd_export(FILE *f)
char *cp;
char *dom, *path;
nfs_export *found = NULL;
- struct in_addr addr;
- struct hostent *he = NULL;
-
+ struct addrinfo *ai = NULL;
if (readline(fileno(f), &lbuf, &lbuflen) != 1)
return;
@@ -771,12 +775,16 @@ void nfsd_export(FILE *f)
auth_reload();
if (use_ipaddr) {
- if (!inet_aton(dom, &addr))
+ struct addrinfo *tmp;
+ tmp = host_pton(dom);
+ if (tmp == NULL)
+ goto out;
+ ai = client_resolve(tmp->ai_addr);
+ freeaddrinfo(tmp);
goto out;
- he = client_resolve(addr);
}
- found = lookup_export(dom, path, he);
+ found = lookup_export(dom, path, ai);
if (found) {
if (dump_to_cache(f, dom, path, &found->m_export) < 0) {
@@ -792,7 +800,7 @@ void nfsd_export(FILE *f)
xlog(D_CALL, "nfsd_export: found %p path %s", found, path ? path : NULL);
if (dom) free(dom);
if (path) free(path);
- if (he) free(he);
+ freeaddrinfo(ai);
}
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index 5373d81..6571454 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -536,22 +536,21 @@ static void free_exportlist(exports *elist)
static void prune_clients(nfs_export *exp, struct exportnode *e)
{
- struct hostent *hp;
+ struct addrinfo *ai = NULL;
struct groupnode *c, **cp;
cp = &e->ex_groups;
while ((c = *cp) != NULL) {
if (client_gettype(c->gr_name) == MCL_FQDN
- && (hp = gethostbyname(c->gr_name))) {
- hp = hostent_dup(hp);
- if (client_check(exp->m_client, hp)) {
+ && (ai = host_addrinfo(c->gr_name))) {
+ if (client_check(exp->m_client, ai)) {
*cp = c->gr_next;
xfree(c->gr_name);
xfree(c);
- xfree (hp);
+ freeaddrinfo(ai);
continue;
}
- xfree (hp);
+ freeaddrinfo(ai);
}
cp = &(c->gr_next);
}