[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-29-g3403c6c

Jeremy Allison jra at samba.org
Fri Oct 12 20:38:36 GMT 2007


The branch, v3-2-test has been updated
       via  3403c6c330b886c86d6d856c3ffc13b043fd6fc1 (commit)
      from  754671b8be0bf73a9e1fe7ff420a1b7a1cd501b7 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-2-test


- Log -----------------------------------------------------------------
commit 3403c6c330b886c86d6d856c3ffc13b043fd6fc1
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Oct 12 13:38:04 2007 -0700

    Convert get_peer_addr() to IPv6. Only is_myname_or_ipaddr()
    lefto to do then I can fix the lib/access.c functions.
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source/lib/util_sock.c |  167 ++++++++++++++++++++++++++++++++----------------
 1 files changed, 112 insertions(+), 55 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index 5a96bb7..8c5d1b6 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -1547,40 +1547,101 @@ int open_udp_socket(const char *host, int port)
 }
 
 /*******************************************************************
+ Return the IP addr of the remote end of a socket as a string.
+ Optionally return the struct sockaddr_storage.
+ ******************************************************************/
+
+static const char *get_peer_addr_internal(int fd,
+				struct sockaddr_storage *pss,
+				socklen_t *plength)
+{
+	struct sockaddr_storage ss;
+	socklen_t length = sizeof(ss);
+	static char addr_buf[INET6_ADDRSTRLEN];
+
+	safe_strcpy(addr_buf,"0.0.0.0",sizeof(addr_buf)-1);
+
+	if (fd == -1) {
+		return addr_buf;
+	}
+
+	if (pss == NULL) {
+		pss = &ss;
+	}
+	if (plength == NULL) {
+		plength = &length;
+	}
+
+	if (getpeername(fd, (struct sockaddr *)pss, plength) < 0) {
+		DEBUG(0,("getpeername failed. Error was %s\n",
+					strerror(errno) ));
+		return addr_buf;
+	}
+
+	print_sockaddr(addr_buf,
+			sizeof(addr_buf),
+			pss,
+			*plength);
+	return addr_buf;
+}
+
+
+/*******************************************************************
  Matchname - determine if host name matches IP address. Used to
  confirm a hostname lookup to prevent spoof attacks.
 ******************************************************************/
 
-static bool matchname(char *remotehost,struct in_addr  addr)
+static bool matchname(const char *remotehost,
+		const struct sockaddr_storage *pss,
+		socklen_t len)
 {
-	struct hostent *hp;
-	int     i;
+	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;
 
-	if ((hp = sys_gethostbyname(remotehost)) == 0) {
-		DEBUG(0,("sys_gethostbyname(%s): lookup failure.\n",
-					remotehost));
+	ret = getaddrinfo(remotehost, NULL,
+			&hints,
+			&res);
+
+	if (ret || res == NULL) {
+		DEBUG(3,("matchname: getaddrinfo failed for "
+			"name %s [%s]\n",
+			remotehost,
+			gai_strerror(ret) ));
 		return false;
 	}
 
 	/*
-	 * Make sure that gethostbyname() returns the "correct" host name.
-	 * Unfortunately, gethostbyname("localhost") sometimes yields
-	 * "localhost.domain". Since the latter host name comes from the
-	 * local DNS, we just have to trust it (all bets are off if the local
-	 * DNS is perverted). We always check the address list, though.
+	 * Make sure that getaddrinfo() returns the "correct" host name.
 	 */
 
-	if (!strequal(remotehost, hp->h_name)
-	    && !strequal(remotehost, "localhost")) {
-		DEBUG(0,("host name/name mismatch: %s != %s\n",
-			 remotehost, hp->h_name));
+	if (res->ai_canonname == NULL ||
+		(!strequal(remotehost, res->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);
 		return false;
 	}
 
 	/* Look up the host address in the address list we just got. */
-	for (i = 0; hp->h_addr_list[i]; i++) {
-		if (memcmp(hp->h_addr_list[i], (char *)&addr,sizeof(addr)) == 0)
+	for (ailist = res; ailist; ailist = ailist->ai_next) {
+		if (!ailist->ai_addr) {
+			continue;
+		}
+		if (addr_equal((const struct sockaddr_storage *)ailist->ai_addr,
+					pss)) {
+			freeaddrinfo(res);
 			return true;
+		}
 	}
 
 	/*
@@ -1589,8 +1650,14 @@ static bool matchname(char *remotehost,struct in_addr  addr)
 	 * it, but that could be dangerous, too.
 	 */
 
-	DEBUG(0,("host name/address mismatch: %s != %s\n",
-		 inet_ntoa(addr), hp->h_name));
+	DEBUG(0,("matchname: host name/address mismatch: %s != %s\n",
+		print_sockaddr(addr_buf,
+			sizeof(addr_buf),
+			pss,
+			len),
+		 res->ai_canonname ? res->ai_canonname : "(NULL)"));
+
+	freeaddrinfo(res);
 	return false;
 }
 
@@ -1600,12 +1667,13 @@ static bool matchname(char *remotehost,struct in_addr  addr)
 
 const char *get_peer_name(int fd, bool force_lookup)
 {
-	static pstring name_buf;
-	pstring tmp_name;
 	static fstring addr_buf;
-	struct hostent *hp;
-	struct in_addr addr;
+	static pstring name_buf;
+	struct sockaddr_storage ss;
+	socklen_t length = sizeof(ss);
 	const char *p;
+	int ret;
+	pstring tmp_name;
 
 	/* reverse lookups can be *very* expensive, and in many
 	   situations won't work because many networks don't link dhcp
@@ -1615,28 +1683,37 @@ const char *get_peer_name(int fd, bool force_lookup)
 		return get_peer_addr(fd);
 	}
 
-	p = get_peer_addr(fd);
+	p = get_peer_addr_internal(fd, &ss, &length);
 
 	/* it might be the same as the last one - save some DNS work */
-	if (strcmp(p, addr_buf) == 0)
+	if (strcmp(p, addr_buf) == 0) {
 		return name_buf;
+	}
 
 	pstrcpy(name_buf,"UNKNOWN");
-	if (fd == -1)
+	if (fd == -1) {
 		return name_buf;
+	}
 
 	fstrcpy(addr_buf, p);
 
-	addr = *interpret_addr2(p);
-
 	/* Look up the remote host name. */
-	if ((hp = gethostbyaddr((char *)&addr.s_addr,
-					sizeof(addr.s_addr), AF_INET)) == 0) {
-		DEBUG(1,("Gethostbyaddr failed for %s\n",p));
+	ret = getnameinfo((struct sockaddr *)&ss,
+			length,
+			name_buf,
+			sizeof(name_buf),
+			NULL,
+			0,
+			NI_NUMERICHOST);
+
+	if (ret) {
+		DEBUG(1,("get_peer_name: getnameinfo failed "
+			"for %s with error %s\n",
+			p,
+			gai_strerror(ret)));
 		pstrcpy(name_buf, p);
 	} else {
-		pstrcpy(name_buf,(char *)hp->h_name);
-		if (!matchname(name_buf, addr)) {
+		if (!matchname(name_buf, &ss, length)) {
 			DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
 			pstrcpy(name_buf,"UNKNOWN");
 		}
@@ -1646,7 +1723,7 @@ const char *get_peer_name(int fd, bool force_lookup)
 	   use --enable-developer or the clobber_region() call will
 	   get you */
 
-	pstrcpy( tmp_name, name_buf );
+	pstrcpy(tmp_name, name_buf );
 	alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));
 	if (strstr(name_buf,"..")) {
 		pstrcpy(name_buf, "UNKNOWN");
@@ -1661,27 +1738,7 @@ const char *get_peer_name(int fd, bool force_lookup)
 
 const char *get_peer_addr(int fd)
 {
-	struct sockaddr_storage ss;
-	socklen_t length = sizeof(ss);
-	static char addr_buf[INET6_ADDRSTRLEN];
-
-	safe_strcpy(addr_buf,"0.0.0.0",sizeof(addr_buf)-1);
-
-	if (fd == -1) {
-		return addr_buf;
-	}
-
-	if (getpeername(fd, (struct sockaddr *)&ss, &length) < 0) {
-		DEBUG(0,("getpeername failed. Error was %s\n",
-					strerror(errno) ));
-		return addr_buf;
-	}
-
-	print_sockaddr(addr_buf,
-			sizeof(addr_buf),
-			&ss,
-			length);
-	return addr_buf;
+	return get_peer_addr_internal(fd, NULL, NULL);
 }
 
 /*******************************************************************


-- 
Samba Shared Repository


More information about the samba-cvs mailing list