X-Git-Url: https://git.decadent.org.uk/gitweb/?p=nfs-utils.git;a=blobdiff_plain;f=utils%2Fstatd%2Fhostname.c;fp=utils%2Fstatd%2Fhostname.c;h=3d10d6f1fa1f59e489388615ec2b80b69bf2d26e;hp=0000000000000000000000000000000000000000;hb=cbd3a131e5c02bbd7b92a72b3ac467d71cfee1c4;hpb=f0d3a4bedccca7cce48296757bc1c8bd59b80828 diff --git a/utils/statd/hostname.c b/utils/statd/hostname.c new file mode 100644 index 0000000..3d10d6f --- /dev/null +++ b/utils/statd/hostname.c @@ -0,0 +1,119 @@ +/* + * Copyright 2009 Oracle. All rights reserved. + * + * This file is part of nfs-utils. + * + * nfs-utils is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * nfs-utils is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with nfs-utils. If not, see . + */ + +/* + * NSM for Linux. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include +#include + +#include "sockaddr.h" +#include "statd.h" +#include "xlog.h" + +/* + * Look up the hostname; report exceptional errors. Caller must + * call freeaddrinfo(3) if a valid addrinfo is returned. + */ +__attribute_malloc__ +static struct addrinfo * +get_addrinfo(const char *hostname, const struct addrinfo *hint) +{ + struct addrinfo *ai = NULL; + int error; + + error = getaddrinfo(hostname, NULL, hint, &ai); + switch (error) { + case 0: + return ai; + case EAI_NONAME: + break; + default: + xlog(D_GENERAL, "%s: failed to resolve host %s: %s", + __func__, hostname, gai_strerror(error)); + } + + return NULL; +} + +/** + * statd_matchhostname - check if two hostnames are equivalent + * @hostname1: C string containing hostname + * @hostname2: C string containing hostname + * + * Returns true if the hostnames are the same, the hostnames resolve + * to the same canonical name, or the hostnames resolve to at least + * one address that is the same. False is returned if the hostnames + * do not match in any of these ways, if either hostname contains + * wildcard characters, if either hostname is a netgroup name, or + * if an error occurs. + */ +_Bool +statd_matchhostname(const char *hostname1, const char *hostname2) +{ + struct addrinfo *ai1, *ai2, *results1 = NULL, *results2 = NULL; + struct addrinfo hint = { + .ai_family = AF_UNSPEC, + .ai_flags = AI_CANONNAME, + .ai_protocol = (int)IPPROTO_UDP, + }; + _Bool result = false; + + if (strcasecmp(hostname1, hostname2) == 0) { + result = true; + goto out; + } + + results1 = get_addrinfo(hostname1, &hint); + if (results1 == NULL) + goto out; + results2 = get_addrinfo(hostname2, &hint); + if (results2 == NULL) + goto out; + + if (strcasecmp(results1->ai_canonname, results2->ai_canonname) == 0) { + result = true; + goto out; + } + + for (ai1 = results1; ai1 != NULL; ai1 = ai1->ai_next) + for (ai2 = results2; ai2 != NULL; ai2 = ai2->ai_next) + if (nfs_compare_sockaddr(ai1->ai_addr, ai2->ai_addr)) { + result = true; + break; + } + +out: + freeaddrinfo(results2); + freeaddrinfo(results1); + + xlog(D_CALL, "%s: hostnames %s", __func__, + (result ? "matched" : "did not match")); + return result; +}