[SCM] Samba Shared Repository - branch master updated

Matthieu Patou mat at samba.org
Fri Nov 11 14:03:02 MST 2011


The branch, master has been updated
       via  691fb36 s4: Simple test script to create lots of contacts to stress the LDB
       via  7c9b3cd s4-librpc: do not limit to the first IP when trying to do a rpc connection
       via  5d18e57 s4-socket: allow connect_multi_next_socket to try all the IP for a given host
      from  29b5a95 py_passdb: Cannot steal an item pointer from an array

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 691fb365f8405d92a269abcef1028aa648d12580
Author: Matthieu Patou <mat at matws.net>
Date:   Fri Nov 11 19:01:54 2011 +0100

    s4: Simple test script to create lots of contacts to stress the LDB
    
    Autobuild-User: Matthieu Patou <mat at samba.org>
    Autobuild-Date: Fri Nov 11 22:02:53 CET 2011 on sn-devel-104

commit 7c9b3cdcf79088ff284d2383676d3f26ae42f8fb
Author: Matthieu Patou <mat at matws.net>
Date:   Thu Nov 10 20:59:09 2011 +0100

    s4-librpc: do not limit to the first IP when trying to do a rpc connection
    
    The function continue_ip_resolve_name was calling resolve_name_recv which returns
    only the first IP for a given hostname.
    Instead we use resolve_name_multiple_recv which returns all the IP for a given
    hostname. This kind of problem can occur if a host has more than 1 IP but is listenning
    only on 1.

commit 5d18e57bec9db9444ae738c24ef63b21e3197a77
Author: Matthieu Patou <mat at matws.net>
Date:   Thu Nov 10 15:36:22 2011 +0100

    s4-socket: allow connect_multi_next_socket to try all the IP for a given host
    
    This fix an incorrect behavior which was that if a host has 2 IP but
    was listening on only 1 (and the second one) connect_multi_next_socket
    was not able to connect because it used only the first result.

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

Summary of changes:
 source4/lib/socket/connect_multi.c                 |   33 ++++++++++-----
 source4/librpc/rpc/dcerpc_sock.c                   |   32 +++++++++++---
 .../devel/{chgtdcpass => addlotscontacts}          |   43 +++++++++++++++++--
 3 files changed, 84 insertions(+), 24 deletions(-)
 copy source4/scripting/devel/{chgtdcpass => addlotscontacts} (59%)
 mode change 100755 => 100644


Changeset truncated at 500 lines:

diff --git a/source4/lib/socket/connect_multi.c b/source4/lib/socket/connect_multi.c
index 5358606..2b926c8 100644
--- a/source4/lib/socket/connect_multi.c
+++ b/source4/lib/socket/connect_multi.c
@@ -33,7 +33,8 @@
   overall state
 */
 struct connect_multi_state {
-	struct socket_address *server_address;
+	struct socket_address **server_address;
+	unsigned num_address, current_address, current_port;
 	int num_ports;
 	uint16_t *ports;
 
@@ -125,14 +126,18 @@ static void connect_multi_next_socket(struct composite_context *result)
 	struct composite_context *creq;
 	int next = multi->num_connects_sent;
 
-	if (next == multi->num_ports) {
+	if (next == multi->num_address * multi->num_ports) {
 		/* don't do anything, just wait for the existing ones to finish */
 		return;
 	}
 
+	if (multi->current_address == multi->num_address) {
+		multi->current_address = 0;
+		multi->current_port += 1;
+	}
 	multi->num_connects_sent += 1;
 
-	if (multi->server_address == NULL) {
+	if (multi->server_address == NULL || multi->server_address[multi->current_address] == NULL) {
 		composite_error(result, NT_STATUS_OBJECT_NAME_NOT_FOUND);
 		return;
 	}
@@ -141,13 +146,14 @@ static void connect_multi_next_socket(struct composite_context *result)
 	if (composite_nomem(state, result)) return;
 
 	state->result = result;
-	result->status = socket_create(multi->server_address->family, SOCKET_TYPE_STREAM, &state->sock, 0);
+	result->status = socket_create(multi->server_address[multi->current_address]->family,
+					SOCKET_TYPE_STREAM, &state->sock, 0);
 	if (!composite_is_ok(result)) return;
 
-	state->addr = socket_address_copy(state, multi->server_address);
+	state->addr = socket_address_copy(state, multi->server_address[multi->current_address]);
 	if (composite_nomem(state->addr, result)) return;
 
-	socket_address_set_port(state->addr, multi->ports[next]);
+	socket_address_set_port(state->addr, multi->ports[multi->current_port]);
 
 	talloc_steal(state, state->sock);
 
@@ -157,12 +163,13 @@ static void connect_multi_next_socket(struct composite_context *result)
 	if (composite_nomem(creq, result)) return;
 	talloc_steal(state, creq);
 
+	multi->current_address++;
 	composite_continue(result, creq, continue_one, state);
 
-	/* if there are more ports to go then setup a timer to fire when we have waited
+	/* if there are more ports / addresses to go then setup a timer to fire when we have waited
 	   for a couple of milli-seconds, when that goes off we try the next port regardless
 	   of whether this port has completed */
-	if (multi->num_ports > multi->num_connects_sent) {
+	if (multi->num_ports * multi->num_address > multi->num_connects_sent) {
 		/* note that this timer is a child of the single
 		   connect attempt state, so it will go away when this
 		   request completes */
@@ -194,12 +201,14 @@ static void continue_resolve_name(struct composite_context *creq)
 	struct connect_multi_state *multi = talloc_get_type(result->private_data, 
 							    struct connect_multi_state);
 	struct socket_address **addr;
+	unsigned i;
 
 	result->status = resolve_name_all_recv(creq, multi, &addr, NULL);
 	if (!composite_is_ok(result)) return;
 
-	/* Let's just go for the first for now */
-	multi->server_address = addr[0];
+	for(i=0; addr[i]; i++);
+	multi->num_address = i;
+	multi->server_address = talloc_steal(multi, addr);
 
 	connect_multi_next_socket(result);
 }
@@ -227,8 +236,8 @@ static void continue_one(struct composite_context *creq)
 
 	talloc_free(state);
 
-	if (NT_STATUS_IS_OK(status) || 
-	    multi->num_connects_recv == multi->num_ports) {
+	if (NT_STATUS_IS_OK(status) ||
+	    multi->num_connects_recv == (multi->num_address * multi->num_ports)) {
 		result->status = status;
 		composite_done(result);
 		return;
diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c
index d0d28bc..a291996 100644
--- a/source4/librpc/rpc/dcerpc_sock.c
+++ b/source4/librpc/rpc/dcerpc_sock.c
@@ -362,7 +362,8 @@ static NTSTATUS dcerpc_pipe_open_socket_recv(struct composite_context *c)
 struct pipe_tcp_state {
 	const char *server;
 	const char *target_hostname;
-	const char *address;
+	const char **addresses;
+	uint32_t index;
 	uint32_t port;
 	struct socket_address *localaddr;
 	struct socket_address *srvaddr;
@@ -382,11 +383,12 @@ static void continue_ip_resolve_name(struct composite_context *ctx)
 						   struct pipe_tcp_state);
 	struct composite_context *sock_ip_req;
 
-	c->status = resolve_name_recv(ctx, s, &s->address);
+	c->status = resolve_name_multiple_recv(ctx, s, &s->addresses);
 	if (!composite_is_ok(c)) return;
 
 	/* prepare server address using host ip:port and transport name */
-	s->srvaddr = socket_address_from_strings(s->conn, "ip", s->address, s->port);
+	s->srvaddr = socket_address_from_strings(s->conn, "ip", s->addresses[s->index], s->port);
+	s->index++;
 	if (composite_nomem(s->srvaddr, c)) return;
 
 	sock_ip_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr,
@@ -413,11 +415,27 @@ static void continue_ip_open_socket(struct composite_context *ctx)
 	if (!NT_STATUS_IS_OK(c->status)) {
 		/* something went wrong... */
 		DEBUG(0, ("Failed to connect host %s (%s) on port %d - %s.\n",
-			  s->address, s->target_hostname, 
+			  s->addresses[s->index - 1], s->target_hostname,
 			  s->port, nt_errstr(c->status)));
-
-		composite_error(c, c->status);
-		return;
+		if (s->addresses[s->index]) {
+			struct composite_context *sock_ip_req;
+			talloc_free(s->srvaddr);
+			/* prepare server address using host ip:port and transport name */
+			s->srvaddr = socket_address_from_strings(s->conn, "ip", s->addresses[s->index], s->port);
+			s->index++;
+			if (composite_nomem(s->srvaddr, c)) return;
+
+			sock_ip_req = dcerpc_pipe_open_socket_send(c, s->conn, s->localaddr,
+								s->srvaddr, s->target_hostname,
+								NULL,
+								NCACN_IP_TCP);
+			composite_continue(c, sock_ip_req, continue_ip_open_socket, c);
+
+			return;
+		} else {
+			composite_error(c, c->status);
+			return;
+		}
 	}
 
 	composite_done(c);
diff --git a/source4/scripting/devel/chgtdcpass b/source4/scripting/devel/addlotscontacts
old mode 100755
new mode 100644
similarity index 59%
copy from source4/scripting/devel/chgtdcpass
copy to source4/scripting/devel/addlotscontacts
index 4f5ea15..cc073a3
--- a/source4/scripting/devel/chgtdcpass
+++ b/source4/scripting/devel/addlotscontacts
@@ -30,9 +30,8 @@ from samba.credentials import DONT_USE_KERBEROS
 from samba.auth import system_session
 from samba import param
 from samba.provision import find_provision_key_parameters
-from samba.upgradehelpers import (get_paths,
-                                  get_ldbs,
-                                 update_machine_account_password)
+from samba.upgradehelpers import (get_paths, get_ldbs)
+from ldb import SCOPE_BASE, Message, MessageElement, Dn, FLAG_MOD_ADD
 
 parser = optparse.OptionParser("chgtdcpass [options]")
 sambaopts = options.SambaOptions(parser)
@@ -41,13 +40,17 @@ parser.add_option_group(options.VersionOptions(parser))
 credopts = options.CredentialsOptions(parser)
 parser.add_option_group(credopts)
 
-opts = parser.parse_args()[0]
+(opts, args) = parser.parse_args()
 
 lp = sambaopts.get_loadparm()
 smbconf = lp.configfile
 creds = credopts.get_credentials(lp)
 creds.set_kerberos_state(DONT_USE_KERBEROS)
 
+if len(args) > 0:
+    num_contacts = int(args[0])
+else:
+    num_contacts = 10000
 
 if __name__ == '__main__':
     paths = get_paths(param, smbconf=smbconf)
@@ -59,5 +62,35 @@ if __name__ == '__main__':
     names = find_provision_key_parameters(ldbs.sam, ldbs.secrets, ldbs.idmap,
                                             paths, smbconf, lp)
 
-    update_machine_account_password(ldbs.sam, ldbs.secrets, names)
+    contactdn = "OU=Contacts,%s" % str(names.domaindn)
+    res = ldbs.sam.search(expression="(dn=%s)" % contactdn,
+                    base=str(names.domaindn),
+                    scope=SCOPE_BASE)
+
+    if (len(res) == 0):
+        msg = Message()
+        msg.dn =  Dn(ldbs.sam, contactdn)
+        msg["objectClass"] = MessageElement("organizationalUnit", FLAG_MOD_ADD,
+                                            "objectClass")
+
+        ldbs.sam.add(msg)
+
+    print "Creating %d contacts" % num_contacts
+    count = 0
+    increment = num_contacts / 10
+    if increment > 5000:
+        increment = 5000
+
+    while (count < num_contacts):
+        msg = Message()
+        msg.dn =  Dn(ldbs.sam, "CN=contact%d,%s" % (count + 1, contactdn))
+        msg["objectClass"] = MessageElement("contact", FLAG_MOD_ADD,
+                                            "objectClass")
+
+        if count !=0 and (count % increment) == 0:
+            print "Added contacts: %d" % count
+
+        ldbs.sam.add(msg)
+        count += 1
+
     ldbs.groupedCommit()


-- 
Samba Shared Repository


More information about the samba-cvs mailing list