summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Holder <david.holder@erion.co.uk>2015-05-12 17:40:29 +0100
committerJeremy Allison <jra@samba.org>2015-05-12 23:35:32 +0200
commit6e08bfb4441022a00d0c29205e835a4858a3a57f (patch)
tree49de3592edf9136cb76e8f5ce5d8e02ee8b666e6
parentc324d7901c991a6700abdc3ee701920fea5e5819 (diff)
downloadsamba-6e08bfb4441022a00d0c29205e835a4858a3a57f.tar.gz
Add IPv6 support for determining FQDN during ADS join.
Signed-off-by: David Holder <david.holder@erion.co.uk> Reviewed-by: Jeremy Allison <jra@samba.org> Reviewed-by: Ralph Böhme <rb@sernet.de> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Tue May 12 23:35:32 CEST 2015 on sn-devel-104
-rw-r--r--source3/lib/util.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/source3/lib/util.c b/source3/lib/util.c
index ec0757e18cd..1d768202448 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -1836,48 +1836,60 @@ bool unix_wild_match(const char *pattern, const char *string)
}
/**********************************************************************
- Converts a name to a fully qualified domain name.
- Returns true if lookup succeeded, false if not (then fqdn is set to name)
- Note we deliberately use gethostbyname here, not getaddrinfo as we want
- to examine the h_aliases and I don't know how to do that with getaddrinfo.
-***********************************************************************/
+ Converts a name to a fully qualified domain name.
+ Returns true if lookup succeeded, false if not (then fqdn is set to name)
+ Uses getaddrinfo() with AI_CANONNAME flag to obtain the official
+ canonical name of the host. getaddrinfo() may use a variety of sources
+ including /etc/hosts to obtain the domainname. It expects aliases in
+ /etc/hosts to NOT be the FQDN. The FQDN should come first.
+************************************************************************/
bool name_to_fqdn(fstring fqdn, const char *name)
{
char *full = NULL;
- struct hostent *hp = gethostbyname(name);
+ struct addrinfo hints;
+ struct addrinfo *result;
+ int s;
+
+ /* Configure hints to obtain canonical name */
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
+ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
+ hints.ai_flags = AI_CANONNAME; /* Get host's FQDN */
+ hints.ai_protocol = 0; /* Any protocol */
- if (!hp || !hp->h_name || !*hp->h_name) {
+ s = getaddrinfo(name, NULL, &hints, &result);
+ if (s != 0) {
+ DEBUG(1, ("getaddrinfo: %s\n", gai_strerror(s)));
DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
fstrcpy(fqdn, name);
return false;
}
+ full = result->ai_canonname;
- /* Find out if the fqdn is returned as an alias
+ /* Find out if the FQDN is returned as an alias
* to cope with /etc/hosts files where the first
- * name is not the fqdn but the short name */
- if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
- int i;
- for (i = 0; hp->h_aliases[i]; i++) {
- if (strchr_m(hp->h_aliases[i], '.')) {
- full = hp->h_aliases[i];
- break;
- }
- }
+ * name is not the FQDN but the short name.
+ * getaddrinfo provides no easy way of handling aliases
+ * in /etc/hosts. Users should make sure the FQDN
+ * comes first in /etc/hosts. */
+ if (full && (! strchr_m(full, '.'))) {
+ DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
+ DEBUGADD(1, (" Full qualified domain names (FQDNs) should not be specified\n"));
+ DEBUGADD(1, (" as an alias in /etc/hosts. FQDN should be the first name\n"));
+ DEBUGADD(1, (" prior to any aliases.\n"));
}
if (full && (strcasecmp_m(full, "localhost.localdomain") == 0)) {
DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
DEBUGADD(1, (" Specifying the machine hostname for address 127.0.0.1 may lead\n"));
DEBUGADD(1, (" to Kerberos authentication problems as localhost.localdomain\n"));
DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
- full = hp->h_name;
- }
- if (!full) {
- full = hp->h_name;
}
DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
fstrcpy(fqdn, full);
+ freeaddrinfo(result); /* No longer needed */
return true;
}