return(True);
}
-/****************************************************************************
- Get my own canonical name, including domain.
-****************************************************************************/
-
-BOOL get_mydnsfullname(fstring my_dnsname)
-{
- static fstring dnshostname;
- struct hostent *hp;
-
- if (!*dnshostname) {
- /* get my host name */
- if (gethostname(dnshostname, sizeof(dnshostname)) == -1) {
- *dnshostname = '\0';
- DEBUG(0,("gethostname failed\n"));
- return False;
- }
-
- /* Ensure null termination. */
- dnshostname[sizeof(dnshostname)-1] = '\0';
-
- /* Ensure we get the cannonical name. */
- if (!(hp = sys_gethostbyname(dnshostname))) {
- *dnshostname = '\0';
- return False;
- }
- fstrcpy(dnshostname, hp->h_name);
- }
- fstrcpy(my_dnsname, dnshostname);
- return True;
-}
-
/****************************************************************************
Get my own domain name.
****************************************************************************/
/**********************************************************************
Converts a name to a fully qualified domain name.
- Returns True if lookup succeeded, False if not (then fqdn is set to 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.
***********************************************************************/
-
-BOOL name_to_fqdn(fstring fqdn, const char *name)
-{
- struct hostent *hp = sys_gethostbyname(name);
-
- if ( hp && hp->h_name && *hp->h_name ) {
- char *full = NULL;
-
- /* 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;
- }
- }
- }
- if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
- DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
- DEBUGADD(1, (" Specifing 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);
- return True;
- } else {
+bool name_to_fqdn(fstring fqdn, const char *name)
+{
+ char *full = NULL;
+ struct hostent *hp = gethostbyname(name);
+
+ if (!hp || !hp->h_name || !*hp->h_name) {
DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
fstrcpy(fqdn, name);
- return False;
+ return false;
}
+
+ /* 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;
+ }
+ }
+ }
+ if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
+ DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
+ DEBUGADD(1, (" Specifing 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);
+ return true;
}
/**********************************************************************
static char client_ip_string[INET6_ADDRSTRLEN];
/****************************************************************************
- Return true if a string could be a pure IPv4 address.
+ Return true if a string could be an IPv4 address.
****************************************************************************/
bool is_ipaddress_v4(const char *str)
{
- bool pure_address = true;
- int i;
+ int ret = -1;
+ struct in_addr dest;
- for (i=0; pure_address && str[i]; i++) {
- if (!(isdigit((int)str[i]) || str[i] == '.')) {
- pure_address = false;
- }
+ ret = inet_pton(AF_INET, str, &dest);
+ if (ret > 0) {
+ return true;
}
+ return false;
+}
- /* Check that a pure number is not misinterpreted as an IP */
- pure_address = pure_address && (strchr_m(str, '.') != NULL);
- return pure_address;
+/****************************************************************************
+ Return true if a string could be an IPv4 or IPv6 address.
+****************************************************************************/
+
+bool is_ipaddress(const char *str)
+{
+ int ret = -1;
+
+#if defined(AF_INET6)
+ struct in6_addr dest6;
+
+ ret = inet_pton(AF_INET6, str, &dest6);
+ if (ret > 0) {
+ return true;
+ }
+#endif
+ return is_ipaddress_v4(str);
+}
+
+/*******************************************************************
+ Wrap getaddrinfo...
+******************************************************************/
+
+static bool interpret_string_addr_internal(struct addrinfo **ppres,
+ const char *str, int flags)
+{
+ int ret;
+ struct addrinfo hints;
+
+ memset(&hints, '\0', sizeof(hints));
+ /* By default make sure it supports TCP. */
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = flags;
+
+ ret = getaddrinfo(str, NULL,
+ &hints,
+ ppres);
+ if (ret) {
+ DEBUG(3,("interpret_string_addr_interal: getaddrinfo failed "
+ "for name %s [%s]\n",
+ str,
+ gai_strerror(ret) ));
+ return false;
+ }
+ return true;
}
/****************************************************************************
Interpret an internet address or name into an IP address in 4 byte form.
+ RETURNS IN NETWORK BYTE ORDER (big endian).
****************************************************************************/
uint32 interpret_addr(const char *str)
{
- struct hostent *hp;
- uint32 res;
+ uint32 ret;
- if (strcmp(str,"0.0.0.0") == 0)
- return(0);
- if (strcmp(str,"255.255.255.255") == 0)
- return(0xFFFFFFFF);
-
- /* if it's in the form of an IP address then
+ /* If it's in the form of an IP address then
* get the lib to interpret it */
if (is_ipaddress_v4(str)) {
- res = inet_addr(str);
+ struct in_addr dest;
+
+ if (inet_pton(AF_INET, str, &dest) <= 0) {
+ /* Error - this shouldn't happen ! */
+ DEBUG(0,("interpret_addr: inet_pton failed "
+ "host %s\n",
+ str));
+ return 0;
+ }
+ ret = dest.s_addr; /* NETWORK BYTE ORDER ! */
} else {
- /* otherwise assume it's a network name of some sort and use
- sys_gethostbyname */
- if ((hp = sys_gethostbyname(str)) == 0) {
- DEBUG(3,("sys_gethostbyname: Unknown host. %s\n",str));
+ /* Otherwise assume it's a network name of some sort and use
+ getadddrinfo. */
+ struct addrinfo *res = NULL;
+ struct addrinfo *res_list = NULL;
+ if (!interpret_string_addr_internal(&res_list,
+ str,
+ AI_ADDRCONFIG)) {
+ DEBUG(3,("interpret_addr: Unknown host. %s\n",str));
return 0;
}
- if(hp->h_addr == NULL) {
- DEBUG(3,("sys_gethostbyname: host address is "
+ /* Find the first IPv4 address. */
+ for (res = res_list; res; res = res->ai_next) {
+ if (res->ai_family != AF_INET) {
+ continue;
+ }
+ if (res->ai_addr == NULL) {
+ continue;
+ }
+ break;
+ }
+ if(res == NULL) {
+ DEBUG(3,("interpret_addr: host address is "
"invalid for host %s\n",str));
+ if (res_list) {
+ freeaddrinfo(res_list);
+ }
return 0;
}
- putip((char *)&res,(char *)hp->h_addr);
+ putip((char *)&ret,
+ &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr);
+ if (res_list) {
+ freeaddrinfo(res_list);
+ }
}
- if (res == (uint32)-1)
- return(0);
+ /* This is so bogus - all callers need fixing... JRA. */
+ if (ret == (uint32)-1) {
+ return 0;
+ }
- return(res);
+ return ret;
}
/*******************************************************************
struct sockaddr_storage.
******************************************************************/
-bool interpret_string_addr(struct sockaddr_storage *pss, const char *str)
+bool interpret_string_addr(struct sockaddr_storage *pss,
+ const char *str,
+ int flags)
{
- int ret;
struct addrinfo *res = NULL;
- struct addrinfo hints;
memset(pss,'\0', sizeof(*pss));
- memset(&hints, '\0', sizeof(hints));
- /* By default make sure it supports TCP. */
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_ADDRCONFIG;
-
- ret = getaddrinfo(str, NULL,
- &hints,
- &res);
-
- if (ret) {
- DEBUG(3,("interpret_string_addr: getaddrinfo failed for "
- "name %s [%s]\n",
- str,
- gai_strerror(ret) ));
+ if (!interpret_string_addr_internal(&res, str, flags|AI_ADDRCONFIG)) {
+ return false;
+ }
+ if (!res) {
return false;
}
-
/* Copy the first sockaddr. */
memcpy(pss, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
{
#if defined(AF_INET6)
if (pss->ss_family == AF_INET) {
- struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr;
+ struct in6_addr *pin6 =
+ &((struct sockaddr_in6 *)pss)->sin6_addr;
return IN6_IS_ADDR_LOOPBACK(pin6);
}
#endif
{
#if defined(AF_INET6)
if (pss->ss_family == AF_INET) {
- struct in6_addr *pin6 = &((struct sockaddr_in6 *)pss)->sin6_addr;
+ struct in6_addr *pin6 =
+ &((struct sockaddr_in6 *)pss)->sin6_addr;
return IN6_IS_ADDR_UNSPECIFIED(pin6);
}
#endif
int open_socket_in(int type,
int port,
int dlevel,
- uint32 socket_addr,
+ uint32 socket_addr, /* NETWORK BYTE ORDER */
bool rebind )
{
struct sockaddr_in sock;
const struct sockaddr_storage *pss,
socklen_t len)
{
- struct addrinfo hints;
struct addrinfo *res = NULL;
struct addrinfo *ailist = NULL;
char addr_buf[INET6_ADDRSTRLEN];
- int ret = -1;
-
- memset(&hints,'\0',sizeof(struct addrinfo));
- /* By default make sure it supports TCP. */
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_ADDRCONFIG|AI_CANONNAME;
-
- ret = getaddrinfo(remotehost, NULL,
- &hints,
- &res);
+ bool ret = interpret_string_addr_internal(&ailist,
+ remotehost,
+ AI_ADDRCONFIG|AI_CANONNAME);
- if (ret || res == NULL) {
+ if (!ret || ailist == NULL) {
DEBUG(3,("matchname: getaddrinfo failed for "
"name %s [%s]\n",
remotehost,
* Make sure that getaddrinfo() returns the "correct" host name.
*/
- if (res->ai_canonname == NULL ||
- (!strequal(remotehost, res->ai_canonname) &&
+ if (ailist->ai_canonname == NULL ||
+ (!strequal(remotehost, ailist->ai_canonname) &&
!strequal(remotehost, "localhost"))) {
DEBUG(0,("matchname: host name/name mismatch: %s != %s\n",
remotehost,
- res->ai_canonname ? res->ai_canonname : "(NULL)"));
- freeaddrinfo(res);
+ ailist->ai_canonname ?
+ ailist->ai_canonname : "(NULL)"));
+ freeaddrinfo(ailist);
return false;
}
/* Look up the host address in the address list we just got. */
- for (ailist = res; ailist; ailist = ailist->ai_next) {
- if (!ailist->ai_addr) {
+ for (res = ailist; res; res = res->ai_next) {
+ if (!res->ai_addr) {
continue;
}
- if (addr_equal((const struct sockaddr_storage *)ailist->ai_addr,
+ if (addr_equal((const struct sockaddr_storage *)res->ai_addr,
pss)) {
- freeaddrinfo(res);
+ freeaddrinfo(ailist);
return true;
}
}
sizeof(addr_buf),
pss,
len),
- res->ai_canonname ? res->ai_canonname : "(NULL)"));
+ ailist->ai_canonname ? ailist->ai_canonname : "(NULL)"));
- freeaddrinfo(res);
+ if (ailist) {
+ freeaddrinfo(ailist);
+ }
return false;
}
#endif /* HAVE_UNIXSOCKET */
}
+/****************************************************************************
+ Get my own canonical name, including domain.
+****************************************************************************/
+
+bool get_mydnsfullname(fstring my_dnsname)
+{
+ static fstring dnshostname;
+
+ if (!*dnshostname) {
+ struct addrinfo *res = NULL;
+ bool ret;
+
+ /* get my host name */
+ if (gethostname(dnshostname, sizeof(dnshostname)) == -1) {
+ *dnshostname = '\0';
+ DEBUG(0,("get_mydnsfullname: gethostname failed\n"));
+ return false;
+ }
+
+ /* Ensure null termination. */
+ dnshostname[sizeof(dnshostname)-1] = '\0';
+
+ ret = interpret_string_addr_internal(&res,
+ dnshostname,
+ AI_ADDRCONFIG|AI_CANONNAME);
+
+ if (!ret || res == NULL) {
+ DEBUG(3,("get_mydnsfullname: getaddrinfo failed for "
+ "name %s [%s]\n",
+ dnshostname,
+ gai_strerror(ret) ));
+ return false;
+ }
+
+ /*
+ * Make sure that getaddrinfo() returns the "correct" host name.
+ */
+
+ if (res->ai_canonname == NULL) {
+ DEBUG(3,("get_mydnsfullname: failed to get "
+ "canonical name for %s\n",
+ dnshostname));
+ freeaddrinfo(res);
+ return false;
+ }
+
+
+ fstrcpy(dnshostname, res->ai_canonname);
+ freeaddrinfo(res);
+ }
+ fstrcpy(my_dnsname, dnshostname);
+ return true;
+}
+
/************************************************************
- Is this my name ? Needs fixing for IPv6.
+ Is this my name ?
************************************************************/
bool is_myname_or_ipaddr(const char *s)
fstring name, dnsname;
char *servername;
- if ( !s ) {
+ if (!s) {
return false;
}
- /* santize the string from '\\name' */
+ /* Santize the string from '\\name' */
+ fstrcpy(name, s);
- fstrcpy( name, s );
-
- servername = strrchr_m( name, '\\' );
- if ( !servername )
+ servername = strrchr_m(name, '\\' );
+ if (!servername) {
servername = name;
- else
+ } else {
servername++;
+ }
- /* optimize for the common case */
-
- if (strequal(servername, global_myname()))
+ /* Optimize for the common case */
+ if (strequal(servername, global_myname())) {
return true;
+ }
- /* check for an alias */
-
- if (is_myname(servername))
+ /* Check for an alias */
+ if (is_myname(servername)) {
return true;
+ }
- /* check for loopback */
-
- if (strequal(servername, "127.0.0.1"))
+ /* Check for loopback */
+ if (strequal(servername, "127.0.0.1") ||
+ strequal(servername, "::1")) {
return true;
+ }
- if (strequal(servername, "localhost"))
+ if (strequal(servername, "localhost")) {
return true;
+ }
- /* maybe it's my dns name */
-
- if ( get_mydnsfullname( dnsname ) )
- if ( strequal( servername, dnsname ) )
+ /* Maybe it's my dns name */
+ if (get_mydnsfullname(dnsname)) {
+ if (strequal(servername, dnsname)) {
return true;
+ }
+ }
- /* handle possible CNAME records */
-
- if ( !is_ipaddress_v4( servername ) ) {
- /* use DNS to resolve the name, but only the first address */
- struct hostent *hp;
-
- if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
- struct in_addr return_ip;
- putip( (char*)&return_ip, (char*)hp->h_addr );
- fstrcpy( name, inet_ntoa( return_ip ) );
+ /* Handle possible CNAME records - convert to an IP addr. */
+ if (!is_ipaddress(servername)) {
+ /* Use DNS to resolve the name, but only the first address */
+ struct sockaddr_storage ss;
+ if (interpret_string_addr(&ss, servername,0)) {
+ print_sockaddr(name,
+ sizeof(name),
+ &ss,
+ sizeof(ss));
servername = name;
}
}
- /* maybe its an IP address? */
- if (is_ipaddress_v4(servername)) {
+ /* Maybe its an IP address? */
+ if (is_ipaddress(servername)) {
struct sockaddr_storage ss;
struct iface_struct nics[MAX_INTERFACES];
int i, n;
- struct in_addr ip;
- ip = *interpret_addr2(servername);
- if (is_zero_ip_v4(ip) || is_loopback_ip_v4(ip)) {
+ if (!interpret_string_addr(&ss, servername, AI_NUMERICHOST)) {
return false;
}
- in_addr_to_sockaddr_storage(&ss, ip);
+ if (is_zero_addr(&ss) || is_loopback_addr(&ss)) {
+ return false;
+ }
n = get_interfaces(nics, MAX_INTERFACES);
for (i=0; i<n; i++) {
- if (nics[i].ip.ss_family != AF_INET) {
- continue;
- }
if (addr_equal(&nics[i].ip, &ss)) {
return true;
}
}
}
- /* no match */
+ /* No match */
return false;
}