[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