[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Sat Oct 2 00:15:02 MDT 2010


The branch, master has been updated
       via  ed5e05a bisect: more bisection options
       via  018d23a script: added bisect-test.py git bisect script
       via  06b27e5 autobuild: show top commit in emails
       via  f9bc389 autobuild: include autobuild.log in logs.tar.gz
       via  eadd282 s4-repl: use the GC principal name for DRS replication connection
       via  9bae4cd s4-rpc: added target_principal binding handle option
       via  ee15dc9 s4-dsdb: added dsdb_search_by_dn_guid()
      from  76232a4 s4:rpc_server/netlogon: don't use dcerpc_binding_handle_call_send/recv() directly

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


- Log -----------------------------------------------------------------
commit ed5e05a15d3a8bea3a4f428d1664c9c5077866c2
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 1 22:07:04 2010 -0700

    bisect: more bisection options
    
    and fixes for the old ones
    
    Autobuild-User: Andrew Tridgell <tridge at samba.org>
    Autobuild-Date: Sat Oct  2 06:14:46 UTC 2010 on sn-devel-104

commit 018d23a2939b6dda41103764d6008b9809b7e192
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 1 21:10:39 2010 -0700

    script: added bisect-test.py git bisect script
    
    this can be used to work out what commit broke a set of tests

commit 06b27e5e3dd35a8a9b7c76c20844a7ad064e1541
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 1 19:53:34 2010 -0700

    autobuild: show top commit in emails

commit f9bc389f60b5bfb6f767299315568ffedd02d993
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 1 19:53:13 2010 -0700

    autobuild: include autobuild.log in logs.tar.gz

commit eadd28233d8df31cddc5c8dd888b768f3ac19730
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 1 19:07:01 2010 -0700

    s4-repl: use the GC principal name for DRS replication connection
    
    this is required when talking to RODCs (for notify calls), and is good
    practice for all DCs
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 9bae4cd3d967f43c32796d03b1c2ee8ae5119e00
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 1 19:05:30 2010 -0700

    s4-rpc: added target_principal binding handle option
    
    this allows you to specify a target SPN for a connection
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit ee15dc96926f505ba7f01ccfcfc2959b507f2b96
Author: Andrew Tridgell <tridge at samba.org>
Date:   Fri Oct 1 19:04:44 2010 -0700

    s4-dsdb: added dsdb_search_by_dn_guid()
    
    this is more efficient than first searching for the DN, then doing a
    search. We should look at using this in lots of existing code
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

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

Summary of changes:
 librpc/rpc/binding.c                 |    4 +-
 script/autobuild.py                  |   23 ++++++++-
 script/bisect-test.py                |   91 ++++++++++++++++++++++++++++++++++
 source4/dsdb/common/util.c           |   26 ++++++++++
 source4/dsdb/repl/drepl_notify.c     |   16 ++++--
 source4/dsdb/repl/drepl_partitions.c |   62 +++++++++++++++++++++++
 source4/dsdb/repl/drepl_service.h    |    4 ++
 source4/libnet/libnet_join.c         |    2 +-
 source4/libnet/libnet_rpc.c          |    2 +-
 source4/librpc/rpc/dcerpc.c          |    2 +-
 source4/librpc/rpc/dcerpc.h          |    1 +
 source4/librpc/rpc/dcerpc_auth.c     |   11 ++++
 source4/librpc/rpc/dcerpc_schannel.c |    2 +-
 13 files changed, 232 insertions(+), 14 deletions(-)
 create mode 100755 script/bisect-test.py


Changeset truncated at 500 lines:

diff --git a/librpc/rpc/binding.c b/librpc/rpc/binding.c
index 42059c0..1b716d0 100644
--- a/librpc/rpc/binding.c
+++ b/librpc/rpc/binding.c
@@ -247,7 +247,7 @@ _PUBLIC_ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struc
 	char *p;
 	int i, j, comma_count;
 
-	b = talloc(mem_ctx, struct dcerpc_binding);
+	b = talloc_zero(mem_ctx, struct dcerpc_binding);
 	if (!b) {
 		return NT_STATUS_NO_MEMORY;
 	}
@@ -651,7 +651,7 @@ _PUBLIC_ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx,
 	NTSTATUS status;
 	struct dcerpc_binding *binding;
 
-	binding = talloc(mem_ctx, struct dcerpc_binding);
+	binding = talloc_zero(mem_ctx, struct dcerpc_binding);
 	NT_STATUS_HAVE_NO_MEMORY(binding);
 
 	ZERO_STRUCT(binding->object);
diff --git a/script/autobuild.py b/script/autobuild.py
index 62117ec..a0c2d9f 100755
--- a/script/autobuild.py
+++ b/script/autobuild.py
@@ -215,6 +215,7 @@ class buildlist(object):
         for b in self.tlist:
             tar.add(b.stdout_path, arcname="%s.stdout" % b.tag)
             tar.add(b.stderr_path, arcname="%s.stderr" % b.tag)
+        tar.add("autobuild.log")
         tar.close()
 
     def remove_logs(self):
@@ -343,11 +344,19 @@ You can see logs of the failed task here:
   http://git.samba.org/%s/samba-autobuild/%s.stdout
   http://git.samba.org/%s/samba-autobuild/%s.stderr
 
+A summary of the autobuild process is here:
+
+  http://git.samba.org/%s/samba-autobuild/autobuild.log
+
 or you can get full logs of all tasks in this job here:
 
   http://git.samba.org/%s/samba-autobuild/logs.tar.gz
 
-''' % (failed_task, errstr, user, failed_tag, user, failed_tag, user)
+The top commit for the tree that was built was:
+
+%s
+
+''' % (failed_task, errstr, user, failed_tag, user, failed_tag, user, user, top_commit_msg)
     msg = MIMEText(text)
     msg['Subject'] = 'autobuild failure for task %s during %s' % (failed_task, failed_stage)
     msg['From'] = 'autobuild at samba.org'
@@ -375,7 +384,14 @@ you can get full logs of all tasks in this job here:
 
   http://git.samba.org/%s/samba-autobuild/logs.tar.gz
 
-''' % (user,)
+''' % user
+
+    text += '''
+The top commit for the tree that was built was:
+
+%s
+''' % top_commit_msg
+
     msg = MIMEText(text)
     msg['Subject'] = 'autobuild success'
     msg['From'] = 'autobuild at samba.org'
@@ -400,6 +416,9 @@ gitroot = find_git_root()
 if gitroot is None:
     raise Exception("Failed to find git root")
 
+# get the top commit message, for emails
+top_commit_msg = run_cmd("git log -1", dir=gitroot, output=True)
+
 try:
     os.makedirs(testbase)
 except Exception, reason:
diff --git a/script/bisect-test.py b/script/bisect-test.py
new file mode 100755
index 0000000..e5f91b0
--- /dev/null
+++ b/script/bisect-test.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+# use git bisect to work out what commit caused a test failure
+# Copyright Andrew Tridgell 2010
+# released under GNU GPL v3 or later
+
+
+from subprocess import call, check_call, Popen, PIPE
+import os, tempfile, sys
+from optparse import OptionParser
+
+parser = OptionParser()
+parser.add_option("", "--tests", help="list of tests to run", default='*')
+parser.add_option("", "--quick", help="use make quicktest", default='')
+parser.add_option("", "--good", help="known good revision (default HEAD~100)", default='HEAD~100')
+parser.add_option("", "--bad", help="known bad revision (default HEAD)", default='HEAD')
+parser.add_option("", "--skip-build-errors", help="skip revision where make fails",
+                  action='store_true', default=False)
+parser.add_option("", "--autogen", help="run autogen before each build",action="store_true", default=False)
+parser.add_option("", "--configure", help="run configure.developer before each build",
+    action="store_true", default=False)
+parser.add_option("", "--clean", help="run make clean before each build",
+    action="store_true", default=False)
+parser.add_option("-j", "", help="use make -j N", dest='N', type='int', action="store", default=1)
+
+(opts, args) = parser.parse_args()
+
+
+def run_cmd(cmd, dir=".", show=True, output=False, checkfail=True):
+    if show:
+        print("Running: '%s' in '%s'" % (cmd, dir))
+    if output:
+        return Popen([cmd], shell=True, stdout=PIPE, cwd=dir).communicate()[0]
+    elif checkfail:
+        return check_call(cmd, shell=True, cwd=dir)
+    else:
+        return call(cmd, shell=True, cwd=dir)
+
+def find_git_root():
+    '''get to the top of the git repo'''
+    p=os.getcwd()
+    while p != '/':
+        if os.path.isdir(os.path.join(p, ".git")):
+            return p
+        p = os.path.abspath(os.path.join(p, '..'))
+    return None
+
+cwd = os.getcwd()
+gitroot = find_git_root()
+
+# create a bisect script
+f = tempfile.NamedTemporaryFile(delete=False)
+f.write("set -x\n")
+f.write("cd %s || exit 125\n" % cwd)
+if opts.autogen:
+    f.write("./autogen.sh || exit 125\n")
+if opts.configure:
+    f.write("./configure.developer || exit 125\n")
+if opts.clean:
+    f.write("make clean || exit 125\n")
+if opts.skip_build_errors:
+    f.write("make -j %u || exit 125\n" % opts.N)
+else:
+    f.write("make -j %u || exit 1\n" % opts.N)
+if opts.quick:
+    target="quicktest"
+else:
+    target="test"
+f.write("make -j %u %s TESTS='%s' FAIL_IMMEDIATELY=1 || exit 1\n" % (opts.N, target, opts.tests))
+f.write("exit 0\n")
+f.close()
+
+def cleanup():
+    run_cmd("git bisect reset", dir=gitroot)
+    os.unlink(f.name)
+    sys.exit(-1)
+
+# run bisect
+ret = -1
+try:
+    run_cmd("git bisect reset", dir=gitroot, show=False, checkfail=False)
+    run_cmd("git bisect start %s %s --" % (opts.bad, opts.good), dir=gitroot)
+    ret = run_cmd("git bisect run bash %s" % f.name, dir=gitroot, show=True, checkfail=False)
+except KeyboardInterrupt:
+    print("Cleaning up")
+    cleanup()
+except Exception, reason:
+    print("Failed bisect: %s" % reason)
+    cleanup()
+
+os.unlink(f.name)
+sys.exit(ret)
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 3259eab..7e60901 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -3760,6 +3760,32 @@ int dsdb_search_dn(struct ldb_context *ldb,
 }
 
 /*
+  search for attrs on one DN, by the GUID of the DN, allowing for
+  dsdb_flags controls
+ */
+int dsdb_search_by_dn_guid(struct ldb_context *ldb,
+			   TALLOC_CTX *mem_ctx,
+			   struct ldb_result **_res,
+			   const struct GUID *guid,
+			   const char * const *attrs,
+			   uint32_t dsdb_flags)
+{
+	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+	struct ldb_dn *dn;
+	int ret;
+
+	dn = ldb_dn_new_fmt(tmp_ctx, ldb, "<GUID=%s>", GUID_string(tmp_ctx, guid));
+	if (!ldb_dn_validate(dn)) {
+		talloc_free(tmp_ctx);
+		return LDB_ERR_INVALID_DN_SYNTAX;
+	}
+
+	ret = dsdb_search_dn(ldb, mem_ctx, _res, dn, attrs, dsdb_flags);
+	talloc_free(tmp_ctx);
+	return ret;
+}
+
+/*
   general search with dsdb_flags for controls
  */
 int dsdb_search(struct ldb_context *ldb,
diff --git a/source4/dsdb/repl/drepl_notify.c b/source4/dsdb/repl/drepl_notify.c
index 6b81901..5d4ed6a 100644
--- a/source4/dsdb/repl/drepl_notify.c
+++ b/source4/dsdb/repl/drepl_notify.c
@@ -292,7 +292,8 @@ static WERROR dreplsrv_schedule_notify_sync(struct dreplsrv_service *service,
 					    struct repsFromToBlob *reps,
 					    TALLOC_CTX *mem_ctx,
 					    uint64_t uSN,
-					    bool is_urgent)
+					    bool is_urgent,
+					    uint32_t replica_flags)
 {
 	struct dreplsrv_notify_operation *op;
 	struct dreplsrv_partition_source_dsa *s;
@@ -307,10 +308,11 @@ static WERROR dreplsrv_schedule_notify_sync(struct dreplsrv_service *service,
 	op = talloc_zero(mem_ctx, struct dreplsrv_notify_operation);
 	W_ERROR_HAVE_NO_MEMORY(op);
 
-	op->service	= service;
-	op->source_dsa	= s;
-	op->uSN         = uSN;
-	op->is_urgent	= is_urgent;
+	op->service	  = service;
+	op->source_dsa	  = s;
+	op->uSN           = uSN;
+	op->is_urgent	  = is_urgent;
+	op->replica_flags = replica_flags;
 
 	DLIST_ADD_END(service->ops.notifies, op, struct dreplsrv_notify_operation *);
 	talloc_steal(service, op);
@@ -350,7 +352,9 @@ static WERROR dreplsrv_notify_check(struct dreplsrv_service *s,
 	/* see if any of our partners need some of our objects */
 	for (i=0; i<count; i++) {
 		struct dreplsrv_partition_source_dsa *sdsa;
+		uint32_t replica_flags;
 		sdsa = dreplsrv_find_source_dsa(p, &reps[i].ctr.ctr1.source_dsa_obj_guid);
+		replica_flags = reps[i].ctr.ctr1.replica_flags;
 		if (sdsa == NULL) continue;
 		if (sdsa->notify_uSN < uSNHighest) {
 			/* we need to tell this partner to replicate
@@ -359,7 +363,7 @@ static WERROR dreplsrv_notify_check(struct dreplsrv_service *s,
 
 			/* check if urgent replication is needed */
 			werr = dreplsrv_schedule_notify_sync(s, p, &reps[i], mem_ctx,
-							     uSNHighest, is_urgent);
+							     uSNHighest, is_urgent, replica_flags);
 			if (!W_ERROR_IS_OK(werr)) {
 				DEBUG(0,(__location__ ": Failed to setup notify to %s for %s\n",
 					 reps[i].ctr.ctr1.other_info->dns_name,
diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c
index 1e787c1..fd0ffd9 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -94,6 +94,61 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 	return WERR_OK;
 }
 
+/*
+  work out the principal to use for DRS replication connections
+ */
+NTSTATUS dreplsrv_get_target_principal(struct dreplsrv_service *s,
+				       TALLOC_CTX *mem_ctx,
+				       const struct repsFromTo1 *rft,
+				       const char **target_principal)
+{
+	TALLOC_CTX *tmp_ctx;
+	struct ldb_result *res;
+	const char *attrs[] = { "dNSHostName", NULL };
+	int ret;
+	const char *hostname;
+	struct ldb_dn *dn;
+
+	*target_principal = NULL;
+
+	tmp_ctx = talloc_new(mem_ctx);
+
+	/* we need to find their hostname */
+	ret = dsdb_find_dn_by_guid(s->samdb, tmp_ctx, &rft->source_dsa_obj_guid, &dn);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(tmp_ctx);
+		/* its OK for their NTDSDSA DN not to be in our database */
+		return NT_STATUS_OK;
+	}
+
+	/* strip off the NTDS Settings */
+	if (!ldb_dn_remove_child_components(dn, 1)) {
+		talloc_free(tmp_ctx);
+		return NT_STATUS_OK;
+	}
+
+	ret = dsdb_search_dn(s->samdb, tmp_ctx, &res, dn, attrs, 0);
+	if (ret != LDB_SUCCESS) {
+		talloc_free(tmp_ctx);
+		/* its OK for their account DN not to be in our database */
+		return NT_STATUS_OK;
+	}
+
+	hostname = ldb_msg_find_attr_as_string(res->msgs[0], "dNSHostName", NULL);
+	if (hostname == NULL) {
+		talloc_free(tmp_ctx);
+		/* its OK to not have a dnshostname */
+		return NT_STATUS_OK;
+	}
+
+	*target_principal = talloc_asprintf(mem_ctx, "GC/%s/%s",
+					    hostname,
+					    lpcfg_dnsdomain(s->task->lp_ctx));
+	talloc_free(tmp_ctx);
+	return NT_STATUS_OK;
+}
+
+
 WERROR dreplsrv_out_connection_attach(struct dreplsrv_service *s,
 				      const struct repsFromTo1 *rft,
 				      struct dreplsrv_out_connection **_conn)
@@ -136,6 +191,13 @@ WERROR dreplsrv_out_connection_attach(struct dreplsrv_service *s,
 			return ntstatus_to_werror(nt_status);
 		}
 
+		/* use the GC principal for DRS replication */
+		nt_status = dreplsrv_get_target_principal(s, conn->binding,
+							  rft, &conn->binding->target_principal);
+		if (!NT_STATUS_IS_OK(nt_status)) {
+			return ntstatus_to_werror(nt_status);
+		}
+
 		DLIST_ADD_END(s->connections, conn, struct dreplsrv_out_connection *);
 
 		DEBUG(2,("dreplsrv_out_connection_attach(%s): create\n", conn->binding->host));
diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h
index 7aeb763..ba1f195 100644
--- a/source4/dsdb/repl/drepl_service.h
+++ b/source4/dsdb/repl/drepl_service.h
@@ -52,6 +52,9 @@ struct dreplsrv_out_connection {
 
 	/* the out going connection to the source dsa */
 	struct dreplsrv_drsuapi_connection *drsuapi;
+
+	/* used to force the GC principal name */
+	const char *principal_name;
 };
 
 struct dreplsrv_partition_source_dsa {
@@ -130,6 +133,7 @@ struct dreplsrv_notify_operation {
 
 	struct dreplsrv_partition_source_dsa *source_dsa;
 	bool is_urgent;
+	uint32_t replica_flags;
 };
 
 struct dreplsrv_service {
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 7992670..da21108 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -96,7 +96,7 @@ static NTSTATUS libnet_JoinADSDomain(struct libnet_context *ctx, struct libnet_J
 		return NT_STATUS_NO_MEMORY;
 	}
 	                                           
-	drsuapi_binding = talloc(tmp_ctx, struct dcerpc_binding);
+	drsuapi_binding = talloc_zero(tmp_ctx, struct dcerpc_binding);
 	if (!drsuapi_binding) {
 		r->out.error_string = NULL;
 		talloc_free(tmp_ctx);
diff --git a/source4/libnet/libnet_rpc.c b/source4/libnet/libnet_rpc.c
index fbf002f..e0781c3 100644
--- a/source4/libnet/libnet_rpc.c
+++ b/source4/libnet/libnet_rpc.c
@@ -772,7 +772,7 @@ static void continue_epm_map_binding_send(struct composite_context *c)
 	s = talloc_get_type(c->private_data, struct rpc_connect_dci_state);
 
 	/* prepare to get endpoint mapping for the requested interface */
-	s->final_binding = talloc(s, struct dcerpc_binding);
+	s->final_binding = talloc_zero(s, struct dcerpc_binding);
 	if (composite_nomem(s->final_binding, c)) return;
 	
 	*s->final_binding = *s->lsa_pipe->binding;
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index 13e3a3e..5a31b6a 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -517,7 +517,7 @@ _PUBLIC_ struct dcerpc_pipe *dcerpc_pipe_init(TALLOC_CTX *mem_ctx, struct tevent
 {
 	struct dcerpc_pipe *p;
 
-	p = talloc(mem_ctx, struct dcerpc_pipe);
+	p = talloc_zero(mem_ctx, struct dcerpc_pipe);
 	if (!p) {
 		return NULL;
 	}
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index b5062a5..4edb521 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -190,6 +190,7 @@ struct dcerpc_binding {
 	struct ndr_syntax_id object;
 	const char *host;
 	const char *target_hostname;
+	const char *target_principal;
 	const char *endpoint;
 	const char **options;
 	const char *localaddress;
diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c
index bca7a8d..95fdbf2 100644
--- a/source4/librpc/rpc/dcerpc_auth.c
+++ b/source4/librpc/rpc/dcerpc_auth.c
@@ -292,6 +292,17 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx,
 		}
 	}
 
+	if (p->binding && p->binding->target_principal) {
+		c->status = gensec_set_target_principal(sec->generic_state,
+							p->binding->target_principal);
+		if (!NT_STATUS_IS_OK(c->status)) {
+			DEBUG(1, ("Failed to set GENSEC target principal to %s: %s\n",
+				  p->binding->target_principal, nt_errstr(c->status)));
+			composite_error(c, c->status);
+			return c;
+		}
+	}
+
 	c->status = gensec_start_mech_by_authtype(sec->generic_state,
 						  auth_type, auth_level);
 	if (!NT_STATUS_IS_OK(c->status)) {
diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c
index 7716323..fc56ecc 100644
--- a/source4/librpc/rpc/dcerpc_schannel.c
+++ b/source4/librpc/rpc/dcerpc_schannel.c
@@ -268,7 +268,7 @@ struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
 	}
 
 	/* allocate binding structure */
-	s->binding = talloc(c, struct dcerpc_binding);
+	s->binding = talloc_zero(c, struct dcerpc_binding);
 	if (composite_nomem(s->binding, c)) return c;
 
 	*s->binding = *s->pipe->binding;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list