[SCM] Samba Shared Repository - branch v3-2-test updated - initial-v3-2-unstable-561-g40c26d5

James Peach jpeach at samba.org
Sun Dec 9 22:20:24 GMT 2007


The branch, v3-2-test has been updated
       via  40c26d55736ae08934e18c27168fff10dd15442f (commit)
       via  5c347cb46d85d04bbba7c99dca7ff9628f977d84 (commit)
       via  4786654992e3cb2280b77406f9217fcec981602c (commit)
       via  87c302e250aacc4d5d6a3cce3f134dd13fa457bf (commit)
       via  e1bfdc17c49da582cdf907e260301ab1946b2ed3 (commit)
       via  ffee51586cfc32a7e394f606e5021ee8fd198559 (commit)
      from  616d6b97e594a846e9b3ac4cbe48538d649462e9 (commit)

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


- Log -----------------------------------------------------------------
commit 40c26d55736ae08934e18c27168fff10dd15442f
Author: James Peach <jpeach at samba.org>
Date:   Sun Dec 9 14:18:54 2007 -0800

    Support fetching very long server lists with RAP_NetServerEnum3.
    
    Use the RAP_NetServerEnum3 server list continuation API for retrieving
    server lists that are too long to fit in a single reply.
    
    Patch from George Colley <gcolley at apple.com>.

commit 5c347cb46d85d04bbba7c99dca7ff9628f977d84
Author: James Peach <jpeach at samba.org>
Date:   Sun Dec 9 14:02:23 2007 -0800

    Choose a better default for sockaddr length.

commit 4786654992e3cb2280b77406f9217fcec981602c
Author: James Peach <jpeach at samba.org>
Date:   Sun Dec 9 14:01:57 2007 -0800

    Specifically ask for IP4 addresses if we don't have IP6 support.

commit 87c302e250aacc4d5d6a3cce3f134dd13fa457bf
Author: James Peach <jpeach at samba.org>
Date:   Sun Dec 9 14:00:25 2007 -0800

    Make sure NULL is defined to the IPv6 test doesn't spuriously fail.

commit e1bfdc17c49da582cdf907e260301ab1946b2ed3
Author: James Peach <jpeach at samba.org>
Date:   Sun Dec 9 13:28:00 2007 -0800

    Fix connect(2) callers to use correct sockaddr size.
    
    Some systems (eg Mac OSX 10.5) require the length passed to match
    the socket address family. This introduces sys_connect() that does
    the right thing, and replaces all uses oc connect(2) with sys_connect().
    
    Note that there are some LGPL callers that still call connect(2)
    directly.

commit ffee51586cfc32a7e394f606e5021ee8fd198559
Author: James Peach <jpeach at samba.org>
Date:   Sun Dec 9 13:22:19 2007 -0800

    Move load_case_tables() to after logging is set up. This can log
    errors.

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

Summary of changes:
 source/client/client.c    |    3 +-
 source/configure.in       |    1 +
 source/lib/ctdbd_conn.c   |    2 +-
 source/lib/sock_exec.c    |    4 +-
 source/lib/system.c       |   18 +++++
 source/lib/util_sock.c    |    9 ++-
 source/libsmb/clirap.c    |  167 +++++++++++++++++++++++++++++++++-----------
 source/libsmb/namequery.c |    5 ++
 8 files changed, 159 insertions(+), 50 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/client/client.c b/source/client/client.c
index 1e2f96c..80e906d 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -4522,7 +4522,6 @@ static int do_message_op(void)
 	if (!client_set_cur_dir("\\")) {
 		exit(ENOMEM);
 	}
-	load_case_tables();
 
 #ifdef KANJI
 	term_code = talloc_strdup(frame,KANJI);
@@ -4546,6 +4545,8 @@ static int do_message_op(void)
 		x_setbuf( dbf, NULL );
 	}
 
+	load_case_tables();
+
 	/* skip argv(0) */
 	pc = poptGetContext("smbclient", argc, (const char **) argv, long_options, 0);
 	poptSetOtherOptionHelp(pc, "service <password>");
diff --git a/source/configure.in b/source/configure.in
index 4eea331..4c72ad3 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -3046,6 +3046,7 @@ fi
 dnl test for ipv6
 AC_CACHE_CHECK([for ipv6 support],samba_cv_HAVE_IPV6,[
 AC_TRY_COMPILE([
+#include <stdlib.h> /* for NULL */
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <netdb.h>],
diff --git a/source/lib/ctdbd_conn.c b/source/lib/ctdbd_conn.c
index 47693ec..899bbcf 100644
--- a/source/lib/ctdbd_conn.c
+++ b/source/lib/ctdbd_conn.c
@@ -135,7 +135,7 @@ static NTSTATUS ctdbd_connect(TALLOC_CTX *mem_ctx,
 	addr.sun_family = AF_UNIX;
 	strncpy(addr.sun_path, sockname, sizeof(addr.sun_path));
 
-	if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+	if (sys_connect(fd, (struct sockaddr *)&addr) == -1) {
 		DEBUG(0, ("connect(%s) failed: %s\n", sockname,
 			  strerror(errno)));
 		close(fd);
diff --git a/source/lib/sock_exec.c b/source/lib/sock_exec.c
index 5e3178c..203d7e9 100644
--- a/source/lib/sock_exec.c
+++ b/source/lib/sock_exec.c
@@ -60,7 +60,7 @@ static int socketpair_tcp(int fd[2])
 
 	sock.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
 
-	if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) == -1) {
+	if (sys_connect(fd[1], (struct sockaddr *)&sock) == -1) {
 		if (errno != EINPROGRESS) goto failed;
 	} else {
 		connect_done = 1;
@@ -70,7 +70,7 @@ static int socketpair_tcp(int fd[2])
 
 	close(listener);
 	if (connect_done == 0) {
-		if (connect(fd[1],(struct sockaddr *)&sock,sizeof(sock)) != 0
+		if (sys_connect(fd[1], (struct sockaddr *)&sock) != 0
 		    && errno != EISCONN) goto failed;
 	}
 
diff --git a/source/lib/system.c b/source/lib/system.c
index 86f3a8c..619627a 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -2472,3 +2472,21 @@ int sys_getnameinfo(const struct sockaddr *psa,
 	}
 	return getnameinfo(psa, salen, host, hostlen, service, servlen, flags);
 }
+
+int sys_connect(int fd, const struct sockaddr * addr)
+{
+	socklen_t salen = addr->sa_len;
+
+	if (addr->sa_family == AF_INET) {
+	    salen = sizeof(struct sockaddr_in);
+	} else if (addr->sa_family == AF_UNIX) {
+	    salen = sizeof(struct sockaddr_un);
+	}
+#if defined(HAVE_IPV6)
+	else if (addr->sa_family == AF_INET6) {
+	    salen = sizeof(struct sockaddr_in6);
+	}
+#endif
+
+	return connect(fd, addr, salen);
+}
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index e919cc5..8f1bd9e 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -1459,7 +1459,7 @@ int open_socket_out(int type,
 	/* and connect it to the destination */
   connect_again:
 
-	ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
+	ret = sys_connect(res, (struct sockaddr *)&sock_out);
 
 	/* Some systems return EAGAIN when they mean EINPROGRESS */
 	if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
@@ -1547,12 +1547,13 @@ bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
 	good_connect = false;
 
 	for (i=0; i<num_addrs; i++) {
+		const struct sockaddr * a = 
+		    (const struct sockaddr *)&(addrs[i]);
 
 		if (sockets[i] == -1)
 			continue;
 
-		if (connect(sockets[i], (struct sockaddr *)&(addrs[i]),
-			    sizeof(*addrs)) == 0) {
+		if (sys_connect(sockets[i], a) == 0) {
 			/* Rather unlikely as we are non-blocking, but it
 			 * might actually happen. */
 			resulting_index = i;
@@ -1681,7 +1682,7 @@ int open_udp_socket(const char *host, int port)
 	sock_out.sin_port = htons(port);
 	sock_out.sin_family = PF_INET;
 
-	if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
+	if (sys_connect(res,(struct sockaddr *)&sock_out)) {
 		close(res);
 		return -1;
 	}
diff --git a/source/libsmb/clirap.c b/source/libsmb/clirap.c
index 410b7cb..54504f6 100644
--- a/source/libsmb/clirap.c
+++ b/source/libsmb/clirap.c
@@ -3,6 +3,7 @@
    client RAP calls
    Copyright (C) Andrew Tridgell         1994-1998
    Copyright (C) Gerald (Jerry) Carter   2004
+   Copyright (C) James Peach		 2007
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -244,57 +245,118 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
 {
 	char *rparam = NULL;
 	char *rdata = NULL;
+	char *rdata_end = NULL;
 	unsigned int rdrcnt,rprcnt;
 	char *p;
 	char param[1024];
 	int uLevel = 1;
-	int count = -1;
 	size_t len;
+	uint32 func = RAP_NetServerEnum2;
+	char *last_entry = NULL;
+	int total_cnt = 0;
+	int return_cnt = 0;
+	int res;
 
 	errno = 0; /* reset */
 
-	/* send a SMBtrans command with api NetServerEnum */
-	p = param;
-	SSVAL(p,0,0x68); /* api number */
-	p += 2;
-	strlcpy(p,"WrLehDz", sizeof(param)-PTR_DIFF(p,param));
-	p = skip_string(param,sizeof(param),p);
+	/*
+	 * This may take more than one transaction, so we should loop until
+	 * we no longer get a more data to process or we have all of the
+	 * items.
+	 */
+	do {
+		/* send a SMBtrans command with api NetServerEnum */
+	        p = param;
+		SIVAL(p,0,func); /* api number */
+	        p += 2;
+	        /* Next time through we need to use the continue api */
+	        func = RAP_NetServerEnum3;
+
+		if (last_entry) {
+			strlcpy(p,"WrLehDOz", sizeof(param)-PTR_DIFF(p,param));
+		} else {
+			strlcpy(p,"WrLehDz", sizeof(param)-PTR_DIFF(p,param));
+		}
 
-	strlcpy(p,"B16BBDz", sizeof(param)-PTR_DIFF(p,param));
+		p = skip_string(param, sizeof(param), p);
+		strlcpy(p,"B16BBDz", sizeof(param)-PTR_DIFF(p,param));
+
+		p = skip_string(param, sizeof(param), p);
+		SSVAL(p,0,uLevel);
+		SSVAL(p,2,CLI_BUFFER_SIZE);
+		p += 4;
+		SIVAL(p,0,stype);
+		p += 4;
+
+		/* If we have more data, tell the server where
+		 * to continue from.
+		 */
+		len = push_ascii(p,
+				last_entry ? last_entry : workgroup,
+				sizeof(param) - PTR_DIFF(p,param) - 1,
+				STR_TERMINATE|STR_UPPER);
+
+		if (len == (size_t)-1) {
+			return false;
+		}
+		p += len;
 
-	p = skip_string(param,sizeof(param),p);
-	SSVAL(p,0,uLevel);
-	SSVAL(p,2,CLI_BUFFER_SIZE);
-	p += 4;
-	SIVAL(p,0,stype);
-	p += 4;
+		if (!cli_api(cli,
+			param, PTR_DIFF(p,param), 8, /* params, length, max */
+			NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */
+		            &rparam, &rprcnt, /* return params, return size */
+		            &rdata, &rdrcnt)) { /* return data, return size */
 
-	len = push_ascii(p, workgroup, sizeof(param)-PTR_DIFF(p,param)-1,
-			STR_TERMINATE|STR_UPPER);
-	if (len == (size_t)-1) {
-		return false;
-	}
-	p += len;
+			/* break out of the loop on error */
+		        res = -1;
+		        break;
+		}
 
-	if (cli_api(cli,
-                    param, PTR_DIFF(p,param), 8,        /* params, length, max */
-                    NULL, 0, CLI_BUFFER_SIZE,               /* data, length, max */
-                    &rparam, &rprcnt,                   /* return params, return size */
-                    &rdata, &rdrcnt                     /* return data, return size */
-                   )) {
-		int res = rparam? SVAL(rparam,0) : -1;
-		char *rdata_end = rdata + rdrcnt;
+		rdata_end = rdata + rdrcnt;
+		res = rparam ? SVAL(rparam,0) : -1;
 
 		if (res == 0 || res == ERRmoredata ||
                     (res != -1 && cli_errno(cli) == 0)) {
-			int i;
+			char *sname = NULL;
+			int i, count;
 			int converter=SVAL(rparam,2);
 
-			count=SVAL(rparam,4);
+			/* Get the number of items returned in this buffer */
+			count = SVAL(rparam, 4);
+
+			/* The next field contains the number of items left,
+			 * including those returned in this buffer. So the
+			 * first time through this should contain all of the
+			 * entries.
+			 */
+			if (total_cnt == 0) {
+			        total_cnt = SVAL(rparam, 6);
+			}
+
+			/* Keep track of how many we have read */
+			return_cnt += count;
 			p = rdata;
 
-			for (i = 0;i < count;i++, p += 26) {
-				char *sname;
+			/* The last name in the previous NetServerEnum reply is
+			 * sent back to server in the NetServerEnum3 request
+			 * (last_entry). The next reply should repeat this entry
+			 * as the first element. We have no proof that this is
+			 * always true, but from traces that seems to be the
+			 * behavior from Window Servers. So first lets do a lot
+			 * of checking, just being paranoid. If the string
+			 * matches then we already saw this entry so skip it.
+			 *
+			 * NOTE: sv1_name field must be null terminated and has
+			 * a max size of 16 (NetBIOS Name).
+			 */
+			if (last_entry && count && p &&
+				(strncmp(last_entry, p, 16) == 0)) {
+			    count -= 1; /* Skip this entry */
+			    return_cnt = -1; /* Not part of total, so don't count. */
+			    p = rdata + 26; /* Skip the whole record */
+			}
+
+			for (i = 0; i < count; i++, p += 26) {
 				int comment_offset;
 				const char *cmnt;
 				const char *p1;
@@ -338,24 +400,45 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
 				fn(s1, stype, s2, state);
 				TALLOC_FREE(frame);
 			}
+
+			/* We are done with the old last entry, so now we can free it */
+			if (last_entry) {
+			        SAFE_FREE(last_entry); /* This will set it to null */
+			}
+
+			/* We always make a copy of  the last entry if we have one */
+			if (sname) {
+			        last_entry = smb_xstrdup(sname);
+			}
+
+			/* If we have more data, but no last entry then error out */
+			if (!last_entry && (res == ERRmoredata)) {
+			        errno = EINVAL;
+			        res = 0;
+			}
+
 		}
-	}
+
+		SAFE_FREE(rparam);
+		SAFE_FREE(rdata);
+	} while ((res == ERRmoredata) && (total_cnt > return_cnt));
 
 	SAFE_FREE(rparam);
 	SAFE_FREE(rdata);
+	SAFE_FREE(last_entry);
 
-	if (count < 0) {
-	    errno = cli_errno(cli);
+	if (res == -1) {
+		errno = cli_errno(cli);
 	} else {
-	    if (!count) {
-		/* this is a very special case, when the domain master for the
-		   work group isn't part of the work group itself, there is something
-		   wild going on */
-		errno = ENOENT;
+		if (!return_cnt) {
+			/* this is a very special case, when the domain master for the
+			   work group isn't part of the work group itself, there is something
+			   wild going on */
+			errno = ENOENT;
+		}
 	    }
-	}
 
-	return(count > 0);
+	return(return_cnt > 0);
 }
 
 /****************************************************************************
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index 9650b5f..e4206e6 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -1244,6 +1244,11 @@ static NTSTATUS resolve_hosts(const char *name, int name_type,
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_flags = AI_ADDRCONFIG;
 
+#if !defined(HAVE_IPV6)
+	/* Unless we have IPv6, we really only want IPv4 addresses back. */
+	hints.ai_family = AF_INET;
+#endif
+
 	ret = getaddrinfo(name,
 			NULL,
 			&hints,


-- 
Samba Shared Repository


More information about the samba-cvs mailing list