[SCM] Samba Shared Repository - branch master updated
Volker Lendecke
vlendec at samba.org
Sun Jun 12 10:20:03 MDT 2011
The branch, master has been updated
via c118bcf s3: Use resolve_wins_send/recv in resolve_wins
via 0dfcf3e s3: Add resolve_wins_send/recv
via 396b646 s3: Add wins_server_tag_ips()
via 12c3c35 s3: Add query_wins_list_send/recv
via f0994c7 s3: Fix IO_TIMEOUT handling for wins queries
via ebf04d7 s3: Remove "struct ip_service" from resolve_wins
via eb16915 nsswitch: Remove some refs to the global winbindd_fd
from d566146 s3-passdb: Implement new pdb trust calls for the default backend
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit c118bcf7556929aadf853a3e0bb7748210126dd2
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jun 3 16:11:17 2011 +0200
s3: Use resolve_wins_send/recv in resolve_wins
Autobuild-User: Volker Lendecke <vlendec at samba.org>
Autobuild-Date: Sun Jun 12 18:19:41 CEST 2011 on sn-devel-104
commit 0dfcf3ef78bb16d79644ee08f58d519e74ff0f0a
Author: Volker Lendecke <vl at samba.org>
Date: Thu Jun 2 14:12:06 2011 +0200
s3: Add resolve_wins_send/recv
commit 396b646123c1aef81c644ae744e65c71b30067d0
Author: Volker Lendecke <vl at samba.org>
Date: Sun Jun 12 14:07:22 2011 +0200
s3: Add wins_server_tag_ips()
For a given tag, return the list of all wins servers
commit 12c3c355966ba7c2da101219ae993fd0ef633026
Author: Volker Lendecke <vl at samba.org>
Date: Sat May 14 18:24:03 2011 +0200
s3: Add query_wins_list_send/recv
commit f0994c749505f11ea115f9e1ae7de52cf25412d0
Author: Volker Lendecke <vl at samba.org>
Date: Sun Jun 12 15:44:19 2011 +0200
s3: Fix IO_TIMEOUT handling for wins queries
commit ebf04d79abdf0a15248a266162c8ec8906ce3c5f
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jun 3 15:49:55 2011 +0200
s3: Remove "struct ip_service" from resolve_wins
commit eb16915e283879aaf0797896fc9bd96b095ff550
Author: Volker Lendecke <vl at samba.org>
Date: Sun Jun 5 16:39:36 2011 +0200
nsswitch: Remove some refs to the global winbindd_fd
-----------------------------------------------------------------------
Summary of changes:
nsswitch/wb_common.c | 18 +-
nsswitch/wins.c | 15 +-
source3/include/proto.h | 12 +-
source3/lib/wins_srv.c | 42 ++++
source3/libsmb/namequery.c | 403 ++++++++++++++++++++++++++++++--------
source3/winbindd/winbindd_wins.c | 18 +--
6 files changed, 394 insertions(+), 114 deletions(-)
Changeset truncated at 500 lines:
diff --git a/nsswitch/wb_common.c b/nsswitch/wb_common.c
index dcfc8a5..80c729a 100644
--- a/nsswitch/wb_common.c
+++ b/nsswitch/wb_common.c
@@ -369,13 +369,14 @@ static int winbind_open_pipe_sock(int recursing, int need_priv)
static int winbind_write_sock(void *buffer, int count, int recursing,
int need_priv)
{
- int result, nwritten;
+ int fd, result, nwritten;
/* Open connection to winbind daemon */
restart:
- if (winbind_open_pipe_sock(recursing, need_priv) == -1) {
+ fd = winbind_open_pipe_sock(recursing, need_priv);
+ if (fd == -1) {
errno = ENOENT;
return -1;
}
@@ -391,7 +392,7 @@ static int winbind_write_sock(void *buffer, int count, int recursing,
/* Catch pipe close on other end by checking if a read()
call would not block by calling poll(). */
- pfd.fd = winbindd_fd;
+ pfd.fd = fd;
pfd.events = POLLIN|POLLHUP;
ret = poll(&pfd, 1, 0);
@@ -412,8 +413,7 @@ static int winbind_write_sock(void *buffer, int count, int recursing,
/* Do the write */
- result = write(winbindd_fd,
- (char *)buffer + nwritten,
+ result = write(fd, (char *)buffer + nwritten,
count - nwritten);
if ((result == -1) || (result == 0)) {
@@ -434,10 +434,12 @@ static int winbind_write_sock(void *buffer, int count, int recursing,
static int winbind_read_sock(void *buffer, int count)
{
+ int fd;
int nread = 0;
int total_time = 0;
- if (winbindd_fd == -1) {
+ fd = winbind_open_pipe_sock(false, false);
+ if (fd == -1) {
return -1;
}
@@ -449,7 +451,7 @@ static int winbind_read_sock(void *buffer, int count)
/* Catch pipe close on other end by checking if a read()
call would not block by calling poll(). */
- pfd.fd = winbindd_fd;
+ pfd.fd = fd;
pfd.events = POLLIN|POLLHUP;
/* Wait for 5 seconds for a reply. May need to parameterise this... */
@@ -475,7 +477,7 @@ static int winbind_read_sock(void *buffer, int count)
/* Do the Read */
- int result = read(winbindd_fd, (char *)buffer + nread,
+ int result = read(fd, (char *)buffer + nread,
count - nread);
if ((result == -1) || (result == 0)) {
diff --git a/nsswitch/wins.c b/nsswitch/wins.c
index 5c9ad2f..d63968b 100644
--- a/nsswitch/wins.c
+++ b/nsswitch/wins.c
@@ -60,8 +60,9 @@ static void nss_wins_init(void)
static struct in_addr *lookup_byname_backend(const char *name, int *count)
{
TALLOC_CTX *frame = talloc_stackframe();
- struct ip_service *address = NULL;
+ struct sockaddr_storage *address = NULL;
struct in_addr *ret = NULL;
+ NTSTATUS status;
int j;
if (!initialised) {
@@ -71,21 +72,20 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
*count = 0;
/* always try with wins first */
- if (NT_STATUS_IS_OK(resolve_wins(name,0x00,&address,count))) {
+ status = resolve_wins(name, 0x00, talloc_tos(),
+ &address, count);
+ if (NT_STATUS_IS_OK(status)) {
if ( (ret = SMB_MALLOC_P(struct in_addr)) == NULL ) {
- free( address );
TALLOC_FREE(frame);
return NULL;
}
- if (address[0].ss.ss_family != AF_INET) {
- free(address);
+ if (address[0].ss_family != AF_INET) {
free(ret);
TALLOC_FREE(frame);
return NULL;
}
- *ret = ((struct sockaddr_in *)(void *)&address[0].ss)
+ *ret = ((struct sockaddr_in *)(void *)address)
->sin_addr;
- free( address );
TALLOC_FREE(frame);
return ret;
}
@@ -95,7 +95,6 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count)
const struct in_addr *bcast = iface_n_bcast_v4(j);
struct sockaddr_storage ss;
struct sockaddr_storage *pss;
- NTSTATUS status;
if (!bcast) {
continue;
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 1cde4be..ad8ae99 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -913,6 +913,8 @@ unsigned wins_srv_count(void);
char **wins_srv_tags(void);
void wins_srv_tags_free(char **list);
struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip);
+bool wins_server_tag_ips(const char *tag, TALLOC_CTX *mem_ctx,
+ struct in_addr **pservers, int *pnum_servers);
unsigned wins_srv_count_tag(const char *tag);
/* The following definitions come from libsmb/clispnego.c */
@@ -1050,9 +1052,17 @@ NTSTATUS name_resolve_bcast(const char *name,
TALLOC_CTX *mem_ctx,
struct sockaddr_storage **return_iplist,
int *return_count);
+struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *name,
+ int name_type);
+NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+ struct sockaddr_storage **addrs,
+ int *num_addrs, uint8_t *flags);
NTSTATUS resolve_wins(const char *name,
int name_type,
- struct ip_service **return_iplist,
+ TALLOC_CTX *mem_ctx,
+ struct sockaddr_storage **return_iplist,
int *return_count);
NTSTATUS internal_resolve_name(const char *name,
int name_type,
diff --git a/source3/lib/wins_srv.c b/source3/lib/wins_srv.c
index 6676f02..f9e8f3b 100644
--- a/source3/lib/wins_srv.c
+++ b/source3/lib/wins_srv.c
@@ -328,6 +328,48 @@ struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip)
return t_ip.ip;
}
+bool wins_server_tag_ips(const char *tag, TALLOC_CTX *mem_ctx,
+ struct in_addr **pservers, int *pnum_servers)
+{
+ const char **list;
+ int i, num_servers;
+ struct in_addr *servers;
+
+ list = lp_wins_server_list();
+ if ((list == NULL) || (list[0] == NULL)) {
+ return false;
+ }
+
+ num_servers = 0;
+
+ for (i=0; list[i] != NULL; i++) {
+ struct tagged_ip t_ip;
+ parse_ip(&t_ip, list[i]);
+ if (strcmp(tag, t_ip.tag) == 0) {
+ num_servers += 1;
+ }
+ }
+
+ servers = talloc_array(mem_ctx, struct in_addr, num_servers);
+ if (servers == NULL) {
+ return false;
+ }
+
+ num_servers = 0;
+
+ for (i=0; list[i] != NULL; i++) {
+ struct tagged_ip t_ip;
+ parse_ip(&t_ip, list[i]);
+ if (strcmp(tag, t_ip.tag) == 0) {
+ servers[num_servers] = t_ip.ip;
+ num_servers += 1;
+ }
+ }
+ *pnum_servers = num_servers;
+ *pservers = servers;
+ return true;
+}
+
/*
return a count of the number of IPs for a particular tag, including
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 511eba4..dc062fb 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -208,6 +208,15 @@ static void set_socket_addr_v4(struct sockaddr_storage *addr)
}
}
+static struct in_addr my_socket_addr_v4(void)
+{
+ struct sockaddr_storage my_addr;
+ struct sockaddr_in *in_addr = (struct sockaddr_in *)((char *)&my_addr);
+
+ set_socket_addr_v4(&my_addr);
+ return in_addr->sin_addr;
+}
+
/****************************************************************************
Generate a random trn_id.
****************************************************************************/
@@ -1423,9 +1432,18 @@ NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
req, struct name_query_state);
NTSTATUS status;
- if (tevent_req_is_nterror(req, &status)
- && !NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
- return status;
+ if (tevent_req_is_nterror(req, &status)) {
+ if (state->bcast &&
+ NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
+ /*
+ * In the broadcast case we collect replies until the
+ * timeout.
+ */
+ status = NT_STATUS_OK;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
if (state->num_addrs == 0) {
return NT_STATUS_NOT_FOUND;
@@ -1793,45 +1811,175 @@ NTSTATUS name_resolve_bcast(const char *name,
NULL, NULL);
}
-/********************************************************
- Resolve via "wins" method.
-*********************************************************/
+struct query_wins_list_state {
+ struct tevent_context *ev;
+ const char *name;
+ uint8_t name_type;
+ struct in_addr *servers;
+ uint32_t num_servers;
+ struct sockaddr_storage server;
+ uint32_t num_sent;
-NTSTATUS resolve_wins(const char *name,
- int name_type,
- struct ip_service **return_iplist,
- int *return_count)
+ struct sockaddr_storage *addrs;
+ int num_addrs;
+ uint8_t flags;
+};
+
+static void query_wins_list_done(struct tevent_req *subreq);
+
+/*
+ * Query a list of (replicating) wins servers in sequence, call them
+ * dead if they don't reply
+ */
+
+static struct tevent_req *query_wins_list_send(
+ TALLOC_CTX *mem_ctx, struct tevent_context *ev,
+ struct in_addr src_ip, const char *name, uint8_t name_type,
+ struct in_addr *servers, int num_servers)
{
- int t, i;
- char **wins_tags;
- struct sockaddr_storage src_ss, *ss_list = NULL;
- struct in_addr src_ip;
+ struct tevent_req *req, *subreq;
+ struct query_wins_list_state *state;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct query_wins_list_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->ev = ev;
+ state->name = name;
+ state->name_type = name_type;
+ state->servers = servers;
+ state->num_servers = num_servers;
+
+ if (state->num_servers == 0) {
+ tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
+ return tevent_req_post(req, ev);
+ }
+
+ in_addr_to_sockaddr_storage(
+ &state->server, state->servers[state->num_sent]);
+
+ subreq = name_query_send(state, state->ev,
+ state->name, state->name_type,
+ false, true, &state->server);
+ state->num_sent += 1;
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ if (!tevent_req_set_endtime(subreq, state->ev,
+ timeval_current_ofs(2, 0))) {
+ tevent_req_nomem(NULL, req);
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, query_wins_list_done, req);
+ return req;
+}
+
+static void query_wins_list_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct query_wins_list_state *state = tevent_req_data(
+ req, struct query_wins_list_state);
NTSTATUS status;
- if (lp_disable_netbios()) {
- DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
- name, name_type));
- return NT_STATUS_INVALID_PARAMETER;
+ status = name_query_recv(subreq, state,
+ &state->addrs, &state->num_addrs,
+ &state->flags);
+ TALLOC_FREE(subreq);
+ if (NT_STATUS_IS_OK(status)) {
+ tevent_req_done(req);
+ return;
}
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
+ tevent_req_nterror(req, status);
+ return;
+ }
+ wins_srv_died(state->servers[state->num_sent-1],
+ my_socket_addr_v4());
- *return_iplist = NULL;
- *return_count = 0;
+ if (state->num_sent == state->num_servers) {
+ tevent_req_nterror(req, NT_STATUS_NOT_FOUND);
+ return;
+ }
- DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
- name, name_type));
+ in_addr_to_sockaddr_storage(
+ &state->server, state->servers[state->num_sent]);
- if (wins_srv_count() < 1) {
- DEBUG(3,("resolve_wins: WINS server resolution selected "
- "and no WINS servers listed.\n"));
- return NT_STATUS_INVALID_PARAMETER;
+ subreq = name_query_send(state, state->ev,
+ state->name, state->name_type,
+ false, true, &state->server);
+ state->num_sent += 1;
+ if (tevent_req_nomem(subreq, req)) {
+ return;
}
+ if (!tevent_req_set_endtime(subreq, state->ev,
+ timeval_current_ofs(2, 0))) {
+ tevent_req_nomem(NULL, req);
+ return;
+ }
+ tevent_req_set_callback(subreq, query_wins_list_done, req);
+}
- /* we try a lookup on each of the WINS tags in turn */
- wins_tags = wins_srv_tags();
+static NTSTATUS query_wins_list_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct sockaddr_storage **addrs,
+ int *num_addrs,
+ uint8_t *flags)
+{
+ struct query_wins_list_state *state = tevent_req_data(
+ req, struct query_wins_list_state);
+ NTSTATUS status;
- if (!wins_tags) {
- /* huh? no tags?? give up in disgust */
- return NT_STATUS_INVALID_PARAMETER;
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
+ }
+ if (addrs != NULL) {
+ *addrs = talloc_move(mem_ctx, &state->addrs);
+ }
+ if (num_addrs != NULL) {
+ *num_addrs = state->num_addrs;
+ }
+ if (flags != NULL) {
+ *flags = state->flags;
+ }
+ return NT_STATUS_OK;
+}
+
+struct resolve_wins_state {
+ int num_sent;
+ int num_received;
+
+ struct sockaddr_storage *addrs;
+ int num_addrs;
+ uint8_t flags;
+};
+
+static void resolve_wins_done(struct tevent_req *subreq);
+
+struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *name,
+ int name_type)
+{
+ struct tevent_req *req, *subreq;
+ struct resolve_wins_state *state;
+ char **wins_tags = NULL;
+ struct sockaddr_storage src_ss;
+ struct in_addr src_ip;
+ int i, num_wins_tags;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct resolve_wins_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ if (wins_srv_count() < 1) {
+ DEBUG(3,("resolve_wins: WINS server resolution selected "
+ "and no WINS servers listed.\n"));
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ goto fail;
}
/* the address we will be sending from */
@@ -1846,80 +1994,164 @@ NTSTATUS resolve_wins(const char *name,
DEBUG(3,("resolve_wins: cannot receive WINS replies "
"on IPv6 address %s\n",
addr));
- wins_srv_tags_free(wins_tags);
- return NT_STATUS_INVALID_PARAMETER;
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ goto fail;
}
- src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr;
+ src_ip = ((const struct sockaddr_in *)(void *)&src_ss)->sin_addr;
- /* in the worst case we will try every wins server with every
- tag! */
- for (t=0; wins_tags && wins_tags[t]; t++) {
- int srv_count = wins_srv_count_tag(wins_tags[t]);
- for (i=0; i<srv_count; i++) {
- struct sockaddr_storage wins_ss;
- struct in_addr wins_ip;
+ wins_tags = wins_srv_tags();
+ if (wins_tags == NULL) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ goto fail;
+ }
- wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
+ num_wins_tags = 0;
+ while (wins_tags[num_wins_tags] != NULL) {
+ num_wins_tags += 1;
+ }
+
+ for (i=0; i<num_wins_tags; i++) {
+ int num_servers, num_alive;
+ struct in_addr *servers, *alive;
+ int j;
+
+ if (!wins_server_tag_ips(wins_tags[i], talloc_tos(),
+ &servers, &num_servers)) {
+ DEBUG(10, ("wins_server_tag_ips failed for tag %s\n",
+ wins_tags[i]));
+ continue;
+ }
+
+ alive = talloc_array(state, struct in_addr, num_servers);
+ if (tevent_req_nomem(alive, req)) {
+ goto fail;
--
Samba Shared Repository
More information about the samba-cvs
mailing list