static void
-init_addrlist(nfs_client *clp, const struct hostent *hp)
+init_addrlist(nfs_client *clp, const struct addrinfo *ai)
{
- struct sockaddr_in sin = {
- .sin_family = AF_INET,
- };
- char **ap;
int i;
- if (hp == NULL)
+ if (ai == NULL)
return;
- ap = hp->h_addr_list;
- for (i = 0; *ap != NULL && i < NFSCLNT_ADDRMAX; i++, ap++) {
- sin.sin_addr = *(struct in_addr *)*ap;
- set_addrlist_in(clp, i, &sin);
+ for (i = 0; (ai != NULL) && (i < NFSCLNT_ADDRMAX); i++) {
+ set_addrlist(clp, i, ai->ai_addr);
+ ai = ai->ai_next;
}
+
clp->m_naddr = i;
}
}
static int
-client_init(nfs_client *clp, const char *hname, const struct hostent *hp)
+client_init(nfs_client *clp, const char *hname, const struct addrinfo *ai)
{
clp->m_hostname = strdup(hname);
if (clp->m_hostname == NULL)
if (clp->m_type == MCL_SUBNETWORK)
return init_subnetwork(clp);
- init_addrlist(clp, hp);
+ init_addrlist(clp, ai);
return 1;
}
{
nfs_client *clp = NULL;
int htype;
- struct hostent *hp = NULL;
+ struct addrinfo *ai = NULL;
htype = client_gettype(hname);
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;
+ ai = host_addrinfo(hname);
+ if (!ai) {
+ xlog(L_ERROR, "Failed to resolve %s", hname);
+ goto out;
}
- /* 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;
+ hname = ai->ai_canonname;
- for (clp = clientlist[htype]; clp; clp = clp->m_next) {
- if (client_check(clp, hp))
+ for (clp = clientlist[htype]; clp; clp = clp->m_next)
+ if (client_check(clp, ai))
break;
- }
} else {
for (clp = clientlist[htype]; clp; clp = clp->m_next) {
if (strcasecmp(hname, clp->m_hostname)==0)
}
if (htype == MCL_FQDN && clp->m_naddr == 0)
- init_addrlist(clp, hp);
+ init_addrlist(clp, ai);
out:
- if (hp)
- free (hp);
-
+ freeaddrinfo(ai);
return clp;
}
+/**
+ * client_dup - create a copy of an nfs_client
+ * @clp: pointer to nfs_client to copy
+ * @ai: pointer to addrinfo used to initialize the new client's addrlist
+ *
+ * Returns a dynamically allocated nfs_client if successful, or
+ * NULL if some problem occurs. Caller must free the returned
+ * nfs_client with free(3).
+ */
nfs_client *
-client_dup(nfs_client *clp, struct hostent *hp)
+client_dup(const nfs_client *clp, const struct addrinfo *ai)
{
nfs_client *new;
new->m_type = MCL_FQDN;
new->m_hostname = NULL;
- if (!client_init(new, hp->h_name, hp)) {
+ if (!client_init(new, ai->ai_canonname, ai)) {
client_free(new);
return NULL;
}
}
}
-struct hostent *
-client_resolve(struct in_addr addr)
+/**
+ * client_resolve - look up an IP address
+ * @sap: pointer to socket address to resolve
+ *
+ * Returns an addrinfo structure, or NULL if some problem occurred.
+ * Caller must free the result with freeaddrinfo(3).
+ */
+struct addrinfo *
+client_resolve(const struct sockaddr *sap)
{
- struct hostent *he = NULL;
+ struct addrinfo *ai = NULL;
if (clientlist[MCL_WILDCARD] || clientlist[MCL_NETGROUP])
- he = get_reliable_hostbyaddr((const char*)&addr, sizeof(addr), AF_INET);
- if (he == NULL)
- he = get_hostent((const char*)&addr, sizeof(addr), AF_INET);
+ ai = host_reliable_addrinfo(sap);
+ if (ai == NULL)
+ ai = host_numeric_addrinfo(sap);
- return he;
+ return ai;
}
/**
* client_compose - Make a list of cached hostnames that match an IP address
- * @he: pointer to hostent containing IP address information to match
+ * @ai: pointer to addrinfo containing IP address information to match
*
* Gather all known client hostnames that match the IP address, and sort
* the result into a comma-separated list.
* returned string with free(3).
*/
char *
-client_compose(struct hostent *he)
+client_compose(const struct addrinfo *ai)
{
char *name = NULL;
int i;
for (i = 0 ; i < MCL_MAXTYPES; i++) {
nfs_client *clp;
for (clp = clientlist[i]; clp ; clp = clp->m_next) {
- if (!client_check(clp, he))
+ if (!client_check(clp, ai))
continue;
name = add_name(name, clp->m_hostname);
}
return new;
}
+static _Bool
+addrs_match4(const struct sockaddr *sa1, const struct sockaddr *sa2)
+{
+ const struct sockaddr_in *si1 = (const struct sockaddr_in *)sa1;
+ const struct sockaddr_in *si2 = (const struct sockaddr_in *)sa2;
+
+ return si1->sin_addr.s_addr == si2->sin_addr.s_addr;
+}
+
+static _Bool
+addrs_match(const struct sockaddr *sa1, const struct sockaddr *sa2)
+{
+ if (sa1->sa_family == sa2->sa_family)
+ switch (sa1->sa_family) {
+ case AF_INET:
+ return addrs_match4(sa1, sa2);
+ }
+
+ return false;
+}
+
/*
- * Check each address listed in @hp against each address
+ * Check each address listed in @ai against each address
* stored in @clp. Return 1 if a match is found, otherwise
* zero.
*/
static int
-check_fqdn(const nfs_client *clp, const struct hostent *hp)
+check_fqdn(const nfs_client *clp, const struct addrinfo *ai)
{
- const struct sockaddr_in *sin;
- struct in_addr addr;
- char **ap;
int i;
- for (ap = hp->h_addr_list; *ap; ap++) {
- addr = *(struct in_addr *)*ap;
-
- for (i = 0; i < clp->m_naddr; i++) {
- sin = get_addrlist_in(clp, i);
- if (sin->sin_addr.s_addr == addr.s_addr)
+ for (; ai; ai = ai->ai_next)
+ for (i = 0; i < clp->m_naddr; i++)
+ if (addrs_match(ai->ai_addr, get_addrlist(clp, i)))
return 1;
- }
+
+ return 0;
+}
+
+static _Bool
+mask_match(const uint32_t a, const uint32_t b, const uint32_t m)
+{
+ return ((a ^ b) & m) == 0;
+}
+
+static int
+check_subnet_v4(const struct sockaddr_in *address,
+ const struct sockaddr_in *mask, const struct addrinfo *ai)
+{
+ for (; ai; ai = ai->ai_next) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)ai->ai_addr;
+
+ if (sin->sin_family != AF_INET)
+ continue;
+
+ if (mask_match(address->sin_addr.s_addr,
+ sin->sin_addr.s_addr,
+ mask->sin_addr.s_addr))
+ return 1;
}
return 0;
}
/*
- * Check each address listed in @hp against the subnetwork or
+ * Check each address listed in @ai against the subnetwork or
* host address stored in @clp. Return 1 if an address in @hp
* matches the host address stored in @clp, otherwise zero.
*/
static int
-check_subnetwork(const nfs_client *clp, const struct hostent *hp)
+check_subnetwork(const nfs_client *clp, const struct addrinfo *ai)
{
- const struct sockaddr_in *address, *mask;
- struct in_addr addr;
- char **ap;
-
- for (ap = hp->h_addr_list; *ap; ap++) {
- address = get_addrlist_in(clp, 0);
- mask = get_addrlist_in(clp, 1);
- addr = *(struct in_addr *)*ap;
-
- if (!((address->sin_addr.s_addr ^ addr.s_addr) &
- mask->sin_addr.s_addr))
- return 1;
+ switch (get_addrlist(clp, 0)->sa_family) {
+ case AF_INET:
+ return check_subnet_v4(get_addrlist_in(clp, 0),
+ get_addrlist_in(clp, 1), ai);
}
+
return 0;
}
* zero.
*/
static int
-check_wildcard(const nfs_client *clp, const struct hostent *hp)
+check_wildcard(const nfs_client *clp, const struct addrinfo *ai)
{
char *cname = clp->m_hostname;
- char *hname = hp->h_name;
+ char *hname = ai->ai_canonname;
+ struct hostent *hp;
char **ap;
if (wildmat(hname, cname))
/* See if hname aliases listed in /etc/hosts or nis[+]
* match the requested wildcard */
- for (ap = hp->h_aliases; *ap; ap++) {
- if (wildmat(*ap, cname))
- return 1;
+ hp = gethostbyname(hname);
+ if (hp != NULL) {
+ for (ap = hp->h_aliases; *ap; ap++)
+ if (wildmat(*ap, cname))
+ return 1;
}
return 0;
}
/*
- * Check if @hp's hostname or aliases fall in a given netgroup.
- * Return 1 if @hp represents a host in the netgroup, otherwise zero.
+ * Check if @ai's hostname or aliases fall in a given netgroup.
+ * Return 1 if @ai represents a host in the netgroup, otherwise
+ * zero.
*/
#ifdef HAVE_INNETGR
static int
-check_netgroup(const nfs_client *clp, const struct hostent *hp)
+check_netgroup(const nfs_client *clp, const struct addrinfo *ai)
{
const char *netgroup = clp->m_hostname + 1;
- const char *hname = hp->h_name;
- struct hostent *nhp = NULL;
- struct sockaddr_in addr;
- int match, i;
+ const char *hname = ai->ai_canonname;
+ struct addrinfo *tmp = NULL;
+ struct hostent *hp;
+ int i, match;
char *dot;
/* First, try to match the hostname without
/* See if hname aliases listed in /etc/hosts or nis[+]
* match the requested netgroup */
- for (i = 0; hp->h_aliases[i]; i++) {
- if (innetgr(netgroup, hp->h_aliases[i], NULL, NULL))
- return 1;
+ hp = gethostbyname(hname);
+ if (hp != NULL) {
+ for (i = 0; hp->h_aliases[i]; i++)
+ if (innetgr(netgroup, hp->h_aliases[i], 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 = nhp->h_name;
+ tmp = host_pton(hname);
+ if (tmp != NULL) {
+ freeaddrinfo(tmp);
if (innetgr(netgroup, hname, NULL, NULL))
return 1;
}
#else /* !HAVE_INNETGR */
static int
check_netgroup(__attribute__((unused)) const nfs_client *clp,
- __attribute__((unused)) const struct hostent *hp)
+ __attribute__((unused)) const struct addrinfo *ai)
{
return 0;
}
/**
* client_check - check if IP address information matches a cached nfs_client
* @clp: pointer to a cached nfs_client record
- * @hp: pointer to hostent containing host IP information
+ * @ai: pointer to addrinfo to compare it with
*
* Returns 1 if the address information matches the cached nfs_client,
* otherwise zero.
*/
int
-client_check(nfs_client *clp, struct hostent *hp)
+client_check(const nfs_client *clp, const struct addrinfo *ai)
{
switch (clp->m_type) {
case MCL_FQDN:
- return check_fqdn(clp, hp);
+ return check_fqdn(clp, ai);
case MCL_SUBNETWORK:
- return check_subnetwork(clp, hp);
+ return check_subnetwork(clp, ai);
case MCL_WILDCARD:
- return check_wildcard(clp, hp);
+ return check_wildcard(clp, ai);
case MCL_NETGROUP:
- return check_netgroup(clp, hp);
+ return check_netgroup(clp, ai);
case MCL_ANONYMOUS:
return 1;
case MCL_GSS:
static void export_init(nfs_export *exp, nfs_client *clp,
struct exportent *nep);
-static int export_check(nfs_export *, struct hostent *, char *);
+static int export_check(const nfs_export *exp, const struct addrinfo *ai,
+ const char *path);
static nfs_export *
- export_allowed_internal(struct hostent *hp, char *path);
+ export_allowed_internal(const struct addrinfo *ai,
+ const char *path);
static void
export_free(nfs_export *exp)
* original hostname from /etc/exports, while the in-core client struct
* gets the newly found FQDN.
*/
-nfs_export *
-export_dup(nfs_export *exp, struct hostent *hp)
+static nfs_export *
+export_dup(nfs_export *exp, const struct addrinfo *ai)
{
nfs_export *new;
nfs_client *clp;
dupexportent(&new->m_export, &exp->m_export);
if (exp->m_export.e_hostname)
new->m_export.e_hostname = xstrdup(exp->m_export.e_hostname);
- clp = client_dup(exp->m_client, hp);
+ clp = client_dup(exp->m_client, ai);
if (clp == NULL) {
export_free(new);
return NULL;
}
}
+/**
+ * export_find - find or create a suitable nfs_export for @ai and @path
+ * @ai: pointer to addrinfo for client
+ * @path: '\0'-terminated ASCII string containing export path
+ *
+ * Returns a pointer to nfs_export data matching @ai and @path,
+ * or NULL if an error occurs.
+ */
nfs_export *
-export_find(struct hostent *hp, char *path)
+export_find(const struct addrinfo *ai, const char *path)
{
nfs_export *exp;
int i;
for (i = 0; i < MCL_MAXTYPES; i++) {
for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
- if (!export_check(exp, hp, path))
+ if (!export_check(exp, ai, path))
continue;
if (exp->m_client->m_type == MCL_FQDN)
return exp;
- return export_dup(exp, hp);
+ return export_dup(exp, ai);
}
}
}
static nfs_export *
-export_allowed_internal (struct hostent *hp, char *path)
+export_allowed_internal(const struct addrinfo *ai, const char *path)
{
nfs_export *exp;
int i;
for (i = 0; i < MCL_MAXTYPES; i++) {
for (exp = exportlist[i].p_head; exp; exp = exp->m_next) {
if (!exp->m_mayexport ||
- !export_check(exp, hp, path))
+ !export_check(exp, ai, path))
continue;
return exp;
}
return NULL;
}
+/**
+ * export_allowed - determine if this export is allowed
+ * @ai: pointer to addrinfo for client
+ * @path: '\0'-terminated ASCII string containing export path
+ *
+ * Returns a pointer to nfs_export data matching @ai and @path,
+ * or NULL if the export is not allowed.
+ */
nfs_export *
-export_allowed(struct hostent *hp, char *path)
+export_allowed(const struct addrinfo *ai, const char *path)
{
nfs_export *exp;
char epath[MAXPATHLEN+1];
/* Try the longest matching exported pathname. */
while (1) {
- exp = export_allowed_internal (hp, epath);
+ exp = export_allowed_internal(ai, epath);
if (exp)
return exp;
/* We have to treat the root, "/", specially. */
}
static int
-export_check(nfs_export *exp, struct hostent *hp, char *path)
+export_check(const nfs_export *exp, const struct addrinfo *ai, const char *path)
{
if (strcmp(path, exp->m_export.e_path))
return 0;
- return client_check(exp->m_client, hp);
+ return client_check(exp->m_client, ai);
}
/**
rmtab_read_wildcard(struct rmtabent *rep)
{
nfs_export *exp, *exp2;
- struct hostent *hp;
+ struct addrinfo *ai;
- hp = gethostbyname(rep->r_client);
- if (hp == NULL)
- return;
- hp = hostent_dup(hp);
- if (hp == NULL)
+ ai = host_addrinfo(rep->r_client);
+ if (ai == NULL)
return;
- exp = export_allowed(hp, rep->r_path);
- free(hp);
+ exp = export_allowed(ai, rep->r_path);
+ freeaddrinfo(ai);
if (exp == NULL)
return;
extern nfs_client * clientlist[MCL_MAXTYPES];
nfs_client * client_lookup(char *hname, int canonical);
-nfs_client * client_dup(nfs_client *, struct hostent *);
+nfs_client * client_dup(const nfs_client *clp,
+ const struct addrinfo *ai);
int client_gettype(char *hname);
-int client_check(nfs_client *, struct hostent *);
+int client_check(const nfs_client *clp,
+ const struct addrinfo *ai);
void client_release(nfs_client *);
void client_freeall(void);
-char * client_compose(struct hostent *he);
-struct hostent * client_resolve(struct in_addr addr);
+char * client_compose(const struct addrinfo *ai);
+struct addrinfo * client_resolve(const struct sockaddr *sap);
int client_member(const char *client,
const char *name);
void export_add(nfs_export *);
void export_reset(nfs_export *);
nfs_export * export_lookup(char *hname, char *path, int caconical);
-nfs_export * export_find(struct hostent *, char *path);
-nfs_export * export_allowed(struct hostent *, char *path);
+nfs_export * export_find(const struct addrinfo *ai,
+ const char *path);
+nfs_export * export_allowed(const struct addrinfo *ai,
+ const char *path);
nfs_export * export_create(struct exportent *, int canonical);
-nfs_export * export_dup(nfs_export *, struct hostent *);
void export_freeall(void);
int export_export(nfs_export *);
int export_unexport(nfs_export *);
{
struct exportent *eep;
nfs_export *exp;
- struct hostent *hp = NULL;
+ struct addrinfo *ai = NULL;
char *path;
char *hname = arg;
int htype;
return;
}
- if ((htype = client_gettype(hname)) == MCL_FQDN &&
- (hp = gethostbyname(hname)) != NULL) {
- struct hostent *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;
- exp = export_find(hp, path);
- hname = hp->h_name;
- } else {
+ if ((htype = client_gettype(hname)) == MCL_FQDN) {
+ ai = host_addrinfo(hname);
+ if (ai != NULL) {
+ exp = export_find(ai, path);
+ hname = ai->ai_canonname;
+ }
+ } else
exp = export_lookup(hname, path, 0);
- }
if (!exp) {
if (!(eep = mkexportent(hname, path, options)) ||
validate_export(exp);
out:
- if (hp) free (hp);
+ freeaddrinfo(ai);
}
static void
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;
/* 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;
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;
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;
}
}
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;
}
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;
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. */
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;
}
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;
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);
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)
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;
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 !! */
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;
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;
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;
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;
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) {
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);
}
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);
}