[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