[SCM] Samba Shared Repository - branch master updated

Andrew Tridgell tridge at samba.org
Wed Aug 25 07:06:56 MDT 2010


The branch, master has been updated
       via  aa54d23... s4-pynet: some systems don't have Py_TYPE()
       via  e69b13c... s4-pyrpc: added a test for talloc behaviour in pidl python code
       via  717ee45... s4-pyglue: added talloc_total_blocks() python call
       via  ba5b3fb... s4-rodc: removed python memory workaround
       via  4f8087c... s4-python: reference substructures onto the parent structure
       via  634e06e... pytalloc: fixed py_talloc_steal()
       via  9218de4... s4-pyglue: pyglue now depends on pytalloc
       via  9563419... s4-rodc: setup secrets database at end of RODC join
       via  5a367f6... s4-pyglue: added talloc_report_full() and talloc_enable_null_tracking()
       via  cb0f8f0... s4-repl: load RODC partitions using msDS-hasFullReplicaNCs
       via  d78417a... s4-pytalloc: use better names for python talloc objects
      from  be59856... s3:smbd: add nfs quota support to the linux-non-sysquota code

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


- Log -----------------------------------------------------------------
commit aa54d239e2abee69f68be554e018fa578f4178af
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 23:04:11 2010 +1000

    s4-pynet: some systems don't have Py_TYPE()
    
    we need a better method than this ....

commit e69b13ccdd008c792f8856a121b188cb11a9afa8
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 15:21:36 2010 +1000

    s4-pyrpc: added a test for talloc behaviour in pidl python code

commit 717ee453dd72511bab2b7fc0e9712e67e5870421
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 15:21:08 2010 +1000

    s4-pyglue: added talloc_total_blocks() python call

commit ba5b3fb2480af2b3f8b5b69e4c161af07241e0c4
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 14:33:17 2010 +1000

    s4-rodc: removed python memory workaround
    
    we can now assign pidl generates structures directly without errors

commit 4f8087cdb95c6036358a41398d73c3ad90c5755c
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 14:32:38 2010 +1000

    s4-python: reference substructures onto the parent structure
    
    when a python object that is part of a parent structure is created, we
    should reference it on the parent structure. This ensures that when
    the child object goes out of scope that the parent structure is still
    valid

commit 634e06e465be7a8921cb95884ec427f48bf812da
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 14:29:59 2010 +1000

    pytalloc: fixed py_talloc_steal()
    
    py_talloc_steal() was implemented as a macro which evaluated it's 2nd
    argument twice. It was often called via a macro with a 2nd argument
    that was a function call, for example an allocation in
    py_talloc_new(). This meant it allocated memory twice, and leaked one
    of them.
    
    This re-implements py_talloc_steal() as a function, so that it only
    does the allocation once.

commit 9218de4b740427a5f381be59ab00a21b0690fb9e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 12:34:30 2010 +1000

    s4-pyglue: pyglue now depends on pytalloc

commit 956341965cee91632aa1a93dd6f9bde453ae1720
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 12:34:15 2010 +1000

    s4-rodc: setup secrets database at end of RODC join
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit 5a367f641ef44a4b58eaea751146a139c70f4afd
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 12:33:38 2010 +1000

    s4-pyglue: added talloc_report_full() and talloc_enable_null_tracking()
    
    these are useful for tracking down leaks and bugs in python scripts
    
    Pair-Programmed-With: Jelmer Vernooij <jelmer at samba.org>

commit cb0f8f0ee087475e63bcc969cf501ce9eae9c98f
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 12:32:48 2010 +1000

    s4-repl: load RODC partitions using msDS-hasFullReplicaNCs
    
    we mark these as incoming_only
    
    Pair-Programmed-With: Andrew Bartlett <abartlet at samba.org>

commit d78417a5d66f9d7a6d282baa6968eb9ba902328e
Author: Andrew Tridgell <tridge at samba.org>
Date:   Wed Aug 25 12:31:32 2010 +1000

    s4-pytalloc: use better names for python talloc objects

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

Summary of changes:
 lib/talloc/pytalloc.c                              |   10 ++++
 lib/talloc/pytalloc.h                              |    2 +-
 pidl/lib/Parse/Pidl/Samba4/Python.pm               |   38 ++++++++-----
 source4/dsdb/repl/drepl_partitions.c               |   30 +++++++++--
 source4/dsdb/repl/drepl_service.h                  |    2 +
 source4/libnet/py_net.c                            |    4 ++
 source4/scripting/python/pyglue.c                  |   50 +++++++++++++++++
 source4/scripting/python/samba/__init__.py         |    3 +
 source4/scripting/python/samba/join.py             |   37 +++++++++++--
 .../python/samba/tests/dcerpc/rpc_talloc.py        |   56 ++++++++++++++++++++
 source4/scripting/python/wscript_build             |    2 +-
 source4/selftest/tests.sh                          |    1 +
 12 files changed, 209 insertions(+), 26 deletions(-)
 create mode 100755 source4/scripting/python/samba/tests/dcerpc/rpc_talloc.py


Changeset truncated at 500 lines:

diff --git a/lib/talloc/pytalloc.c b/lib/talloc/pytalloc.c
index 5ed88ec..92b7b94 100644
--- a/lib/talloc/pytalloc.c
+++ b/lib/talloc/pytalloc.c
@@ -47,10 +47,19 @@ PyObject *py_talloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx,
 	if (talloc_steal(ret->talloc_ctx, mem_ctx) == NULL) {
 		return NULL;
 	}
+	talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
 	ret->ptr = ptr;
 	return (PyObject *)ret;
 }
 
+/**
+ * Import an existing talloc pointer into a Python object.
+ */
+PyObject *py_talloc_steal(PyTypeObject *py_type, void *ptr)
+{
+	return py_talloc_steal_ex(py_type, ptr, ptr);
+}
+
 
 /**
  * Import an existing talloc pointer into a Python object, leaving the
@@ -67,6 +76,7 @@ PyObject *py_talloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, voi
 	if (talloc_reference(ret->talloc_ctx, mem_ctx) == NULL) {
 		return NULL;
 	}
+	talloc_set_name_const(ret->talloc_ctx, py_type->tp_name);
 	ret->ptr = ptr;
 	return (PyObject *)ret;
 }
diff --git a/lib/talloc/pytalloc.h b/lib/talloc/pytalloc.h
index 9b65872..cdcc57b 100644
--- a/lib/talloc/pytalloc.h
+++ b/lib/talloc/pytalloc.h
@@ -43,8 +43,8 @@ void py_talloc_dealloc(PyObject* self);
 #define py_talloc_get_mem_ctx(py_obj)  ((py_talloc_Object *)py_obj)->talloc_ctx
 
 PyObject *py_talloc_steal_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr);
+PyObject *py_talloc_steal(PyTypeObject *py_type, void *ptr);
 PyObject *py_talloc_reference_ex(PyTypeObject *py_type, TALLOC_CTX *mem_ctx, void *ptr);
-#define py_talloc_steal(py_type, talloc_ptr) py_talloc_steal_ex(py_type, talloc_ptr, talloc_ptr)
 #define py_talloc_reference(py_type, talloc_ptr) py_talloc_reference_ex(py_type, talloc_ptr, talloc_ptr)
 
 /* Sane default implementation of reprfunc. */
diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm
index 6adc60c..eb39718 100644
--- a/pidl/lib/Parse/Pidl/Samba4/Python.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm
@@ -158,7 +158,7 @@ sub FromPythonToUnionFunction($$$$$)
 		if ($e->{CASE} eq "default") { $has_default = 1; }
 		$self->indent;
 		if ($e->{NAME}) {
-			$self->ConvertObjectFromPython({}, $mem_ctx, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;");
+			$self->ConvertObjectFromPython({}, $mem_ctx, undef, $e, $name, "ret->$e->{NAME}", "talloc_free(ret); return NULL;");
 		}
 		$self->pidl("break;");
 		$self->deindent;
@@ -209,14 +209,15 @@ sub PythonStruct($$$$$$)
 			$self->indent;
 			$self->pidl("$cname *object = ($cname *)py_talloc_get_ptr(py_obj);");
 			my $mem_ctx = "py_talloc_get_mem_ctx(py_obj)";
+			my $mem_ref = "py_talloc_get_ptr(py_obj)";
 			my $l = $e->{LEVELS}[0];
 			my $nl = GetNextLevel($e, $l);
 			if ($l->{TYPE} eq "POINTER" and 
 				not ($nl->{TYPE} eq "ARRAY" and ($nl->{IS_FIXED} or is_charset_array($e, $nl))) and
 				not ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE}))) {
-				$self->pidl("talloc_free($varname);");
+				$self->pidl("talloc_unlink(py_talloc_get_mem_ctx(py_obj), $varname);");
 			}
-			$self->ConvertObjectFromPython($env, $mem_ctx, $e, "value", $varname, "return -1;");
+			$self->ConvertObjectFromPython($env, $mem_ctx, $mem_ref, $e, "value", $varname, "return -1;");
 			$self->pidl("return 0;");
 			$self->deindent;
 			$self->pidl("}");
@@ -512,7 +513,7 @@ sub PythonFunctionPackIn($$$)
 				$self->pidl("r->in.$e->{NAME} = $val;");
 			}
 		} else {
-			$self->ConvertObjectFromPython($env, "r", $e, "py_$e->{NAME}", "r->in.$e->{NAME}", $fail);
+			$self->ConvertObjectFromPython($env, "r", undef, $e, "py_$e->{NAME}", "r->in.$e->{NAME}", $fail);
 		}
 	}
 	$self->pidl("return true;");
@@ -876,7 +877,7 @@ sub ConvertObjectFromPythonData($$$$$$;$)
 			return;
 		}
 		$self->pidl("PY_CHECK_TYPE($ctype_name, $cvar, $fail);");
-		$self->assign($target, "(".mapTypeName($ctype)." *)py_talloc_get_ptr($cvar)");
+		$self->assign($target, "talloc_reference($mem_ctx, (".mapTypeName($ctype)." *)py_talloc_get_ptr($cvar))");
 		return;
 	}
 
@@ -926,14 +927,14 @@ sub ConvertObjectFromPythonData($$$$$$;$)
 
 }
 
-sub ConvertObjectFromPythonLevel($$$$$$$$)
+sub ConvertObjectFromPythonLevel($$$$$$$$$)
 {
-	my ($self, $env, $mem_ctx, $py_var, $e, $l, $var_name, $fail) = @_;
+	my ($self, $env, $mem_ctx, $mem_ref, $py_var, $e, $l, $var_name, $fail) = @_;
 	my $nl = GetNextLevel($e, $l);
 
 	if ($l->{TYPE} eq "POINTER") {
 		if ($nl->{TYPE} eq "DATA" and Parse::Pidl::Typelist::scalar_is_reference($nl->{DATA_TYPE})) {
-			$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, $var_name, $fail);
+			$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $mem_ref, $py_var, $e, $nl, $var_name, $fail);
 			return;
 		}
 		if ($l->{POINTER_TYPE} ne "ref") {
@@ -944,8 +945,10 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
 			$self->pidl("} else {");
 			$self->indent;
 		}
-		$self->pidl("$var_name = talloc_ptrtype($mem_ctx, $var_name);");
-		$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, $nl, get_value_of($var_name), $fail);
+		# if we want to handle more than one level of pointer in python interfaces
+		# then this is where we would need to allocate it
+		$self->pidl("$var_name = NULL;");
+		$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $mem_ref, $py_var, $e, $nl, get_value_of($var_name), $fail);
 		if ($l->{POINTER_TYPE} ne "ref") {
 			$self->deindent;
 			$self->pidl("}");
@@ -968,10 +971,15 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
 			$self->pidl("int $counter;");
 			if (ArrayDynamicallyAllocated($e, $l)) {
 				$self->pidl("$var_name = talloc_array_ptrtype($mem_ctx, $var_name, PyList_Size($py_var));");
+				$self->pidl("if (!$var_name) { $fail; }");
+				$self->pidl("talloc_set_name_const($var_name, \"ARRAY: $var_name\");");
+				if ($mem_ref) {
+					$self->pidl("if (!talloc_reference($mem_ref, $var_name)) { $fail }");
+				}
 			}
 			$self->pidl("for ($counter = 0; $counter < PyList_Size($py_var); $counter++) {");
 			$self->indent;
-			$self->ConvertObjectFromPythonLevel($env, $var_name, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail);
+			$self->ConvertObjectFromPythonLevel($env, $var_name, undef, "PyList_GetItem($py_var, $counter)", $e, GetNextLevel($e, $l), $var_name."[$counter]", $fail);
 			$self->deindent;
 			$self->pidl("}");
 			$self->deindent;
@@ -996,17 +1004,17 @@ sub ConvertObjectFromPythonLevel($$$$$$$$)
 		$self->deindent;
 		$self->pidl("}");
 	} elsif ($l->{TYPE} eq "SUBCONTEXT") {
-		$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail);
+		$self->ConvertObjectFromPythonLevel($env, $mem_ctx, undef, $py_var, $e, GetNextLevel($e, $l), $var_name, $fail);
 	} else {
 		fatal($e->{ORIGINAL}, "unknown level type $l->{TYPE}");
 	}
 }
 
-sub ConvertObjectFromPython($$$$$$$)
+sub ConvertObjectFromPython($$$$$$$$)
 {
-	my ($self, $env, $mem_ctx, $ctype, $cvar, $target, $fail) = @_;
+	my ($self, $env, $mem_ctx, $mem_ref, $ctype, $cvar, $target, $fail) = @_;
 
-	$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $cvar, $ctype, $ctype->{LEVELS}[0], $target, $fail);
+	$self->ConvertObjectFromPythonLevel($env, $mem_ctx, $mem_ref, $cvar, $ctype, $ctype->{LEVELS}[0], $target, $fail);
 }
 
 sub ConvertScalarToPython($$$)
diff --git a/source4/dsdb/repl/drepl_partitions.c b/source4/dsdb/repl/drepl_partitions.c
index cb45b41..5a11dce 100644
--- a/source4/dsdb/repl/drepl_partitions.c
+++ b/source4/dsdb/repl/drepl_partitions.c
@@ -39,7 +39,7 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 	struct ldb_dn *basedn;
 	struct ldb_result *r;
 	struct ldb_message_element *el;
-	static const char *attrs[] = { "hasMasterNCs", NULL };
+	static const char *attrs[] = { "hasMasterNCs", "msDS-hasFullReplicaNCs", NULL };
 	unsigned int i;
 	int ret;
 
@@ -55,10 +55,9 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 		return WERR_FOOBAR;
 	}
 
+
+
 	el = ldb_msg_find_element(r->msgs[0], "hasMasterNCs");
-	if (!el) {
-		return WERR_FOOBAR;
-	}
 
 	for (i=0; el && i < el->num_values; i++) {
 		const char *v = (const char *)el->values[i].data;
@@ -80,6 +79,29 @@ WERROR dreplsrv_load_partitions(struct dreplsrv_service *s)
 		DEBUG(2, ("dreplsrv_partition[%s] loaded\n", v));
 	}
 
+	el = ldb_msg_find_element(r->msgs[0], "msDS-hasFullReplicaNCs");
+
+	for (i=0; el && i < el->num_values; i++) {
+		const char *v = (const char *)el->values[i].data;
+		struct ldb_dn *pdn;
+		struct dreplsrv_partition *p;
+
+		pdn = ldb_dn_new(s, s->samdb, v);
+		if (!ldb_dn_validate(pdn)) {
+			return WERR_FOOBAR;
+		}
+
+		p = talloc_zero(s, struct dreplsrv_partition);
+		W_ERROR_HAVE_NO_MEMORY(p);
+
+		p->dn = talloc_steal(p, pdn);
+		p->incoming_only = true;
+
+		DLIST_ADD(s->partitions, p);
+
+		DEBUG(2, ("dreplsrv_partition[%s] loaded (incoming only)\n", v));
+	}
+
 	talloc_free(r);
 
 	status = dreplsrv_refresh_partitions(s);
diff --git a/source4/dsdb/repl/drepl_service.h b/source4/dsdb/repl/drepl_service.h
index eefd4da..4019bf7 100644
--- a/source4/dsdb/repl/drepl_service.h
+++ b/source4/dsdb/repl/drepl_service.h
@@ -99,6 +99,8 @@ struct dreplsrv_partition {
 	 * a linked list of all source dsa's we replicate from
 	 */
 	struct dreplsrv_partition_source_dsa *sources;
+
+	bool incoming_only;
 };
 
 typedef void (*dreplsrv_fsmo_callback_t)(struct dreplsrv_service *,
diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c
index 0b1eb7b..79abcd2 100644
--- a/source4/libnet/py_net.c
+++ b/source4/libnet/py_net.c
@@ -407,10 +407,12 @@ static PyObject *py_net_replicate_chunk(py_net_Object *self, PyObject *args, PyO
 
 	switch (level) {
 	case 1:
+#ifdef Py_TYPE
 		if (strcmp("drsuapi.DsGetNCChangesCtr1", Py_TYPE(py_ctr)->tp_name) != 0) {
 			PyErr_SetString(PyExc_TypeError, "Expected DsGetNCChangesCtr1 type for ctr");
 			return NULL;
 		}
+#endif
 		s->chunk.ctr1                         = py_talloc_get_ptr(py_ctr);
 		s->partition.nc                       = *s->chunk.ctr1->naming_context;
 		s->partition.more_data                = s->chunk.ctr1->more_data;
@@ -419,10 +421,12 @@ static PyObject *py_net_replicate_chunk(py_net_Object *self, PyObject *args, PyO
 		s->partition.highwatermark            = s->chunk.ctr1->new_highwatermark;
 		break;
 	case 6:
+#ifdef Py_TYPE
 		if (strcmp("drsuapi.DsGetNCChangesCtr6", Py_TYPE(py_ctr)->tp_name) != 0) {
 			PyErr_SetString(PyExc_TypeError, "Expected DsGetNCChangesCtr6 type for ctr");
 			return NULL;
 		}
+#endif
 		s->chunk.ctr6                         = py_talloc_get_ptr(py_ctr);
 		s->partition.nc                       = *s->chunk.ctr6->naming_context;
 		s->partition.more_data                = s->chunk.ctr6->more_data;
diff --git a/source4/scripting/python/pyglue.c b/source4/scripting/python/pyglue.c
index 5de024c..ec15e77 100644
--- a/source4/scripting/python/pyglue.c
+++ b/source4/scripting/python/pyglue.c
@@ -25,6 +25,7 @@
 #include "param/pyparam.h"
 #include "lib/socket/netif.h"
 #include "lib/socket/netif_proto.h"
+#include "lib/talloc/pytalloc.h"
 
 static PyObject *py_generate_random_str(PyObject *self, PyObject *args)
 {
@@ -164,6 +165,49 @@ static PyObject *py_interface_ips(PyObject *self, PyObject *args)
 	return pylist;
 }
 
+/* print a talloc tree report for a talloc python object */
+static PyObject *py_talloc_report_full(PyObject *self, PyObject *args)
+{
+	PyObject *py_obj;
+	PyTypeObject *type;
+
+	if (!PyArg_ParseTuple(args, "O", &py_obj))
+		return NULL;
+
+	if (py_obj == Py_None) {
+		talloc_report_full(NULL, stdout);
+	} else {
+		type = (PyTypeObject*)PyObject_Type(py_obj);
+		talloc_report_full(py_talloc_get_mem_ctx(py_obj), stdout);
+	}
+	return Py_None;
+}
+
+/* enable null tracking */
+static PyObject *py_talloc_enable_null_tracking(PyObject *self, PyObject *args)
+{
+	talloc_enable_null_tracking();
+	return Py_None;
+}
+
+/* return the number of talloc blocks */
+static PyObject *py_talloc_total_blocks(PyObject *self, PyObject *args)
+{
+	PyObject *py_obj;
+	PyTypeObject *type;
+
+	if (!PyArg_ParseTuple(args, "O", &py_obj))
+		return NULL;
+
+	if (py_obj == Py_None) {
+		return PyLong_FromLong(talloc_total_blocks(NULL));
+	}
+
+	type = (PyTypeObject*)PyObject_Type(py_obj);
+
+	return PyLong_FromLong(talloc_total_blocks(py_talloc_get_mem_ctx(py_obj)));
+}
+
 
 static PyMethodDef py_misc_methods[] = {
 	{ "generate_random_str", (PyCFunction)py_generate_random_str, METH_VARARGS,
@@ -182,6 +226,12 @@ static PyMethodDef py_misc_methods[] = {
 		"set debug level" },
 	{ "interface_ips", (PyCFunction)py_interface_ips, METH_VARARGS,
 		"get interface IP address list"},
+	{ "talloc_report_full", (PyCFunction)py_talloc_report_full, METH_VARARGS,
+		"show a talloc tree for an object"},
+	{ "talloc_enable_null_tracking", (PyCFunction)py_talloc_enable_null_tracking, METH_VARARGS,
+		"enable tracking of the NULL object"},
+	{ "talloc_total_blocks", (PyCFunction)py_talloc_total_blocks, METH_VARARGS,
+		"return talloc block count"},
 	{ NULL }
 };
 
diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py
index 80873dc..72bbb4a 100644
--- a/source4/scripting/python/samba/__init__.py
+++ b/source4/scripting/python/samba/__init__.py
@@ -327,3 +327,6 @@ interface_ips = _glue.interface_ips
 set_debug_level = _glue.set_debug_level
 unix2nttime = _glue.unix2nttime
 generate_random_password = _glue.generate_random_password
+talloc_report_full = _glue.talloc_report_full
+talloc_enable_null_tracking = _glue.talloc_enable_null_tracking
+talloc_total_blocks = _glue.talloc_total_blocks
diff --git a/source4/scripting/python/samba/join.py b/source4/scripting/python/samba/join.py
index 12a944d..c48b53f 100644
--- a/source4/scripting/python/samba/join.py
+++ b/source4/scripting/python/samba/join.py
@@ -21,7 +21,7 @@
 import samba.getopt as options
 from samba.auth import system_session
 from samba.samdb import SamDB
-from samba import gensec
+from samba import gensec, Ldb
 import ldb, samba, sys
 from samba.ndr import ndr_pack, ndr_unpack, ndr_print
 from samba.dcerpc import security
@@ -31,6 +31,9 @@ from samba.provision import secretsdb_self_join, provision, FILL_DRS, find_setup
 from samba.net import Net
 import logging
 
+# this makes debugging easier
+samba.talloc_enable_null_tracking()
+
 class join_ctx:
     '''hold join context variables'''
     pass
@@ -187,10 +190,10 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
         req8.mapping_ctr.num_mappings	     = 0
         req8.mapping_ctr.mappings	     = None
 
-        while True:
-            if not schema:
-                req8.partial_attribute_set = get_rodc_partial_attribute_set(ctx)
+        if not schema:
+            req8.partial_attribute_set = get_rodc_partial_attribute_set(ctx)
 
+        while True:
             (level, ctr) = ctx.drs.DsGetNCChanges(ctx.drs_handle, 8, req8)
             ctx.net.replicate_chunk(ctx.replication_state, level, ctr, schema=schema)
             if ctr.more_data == 0:
@@ -349,6 +352,7 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
         print "Provision OK for domain DN %s" % presult.domaindn
         ctx.local_samdb = presult.samdb
         ctx.lp          = presult.lp
+        ctx.paths       = presult.paths
 
 
     def join_replicate(ctx):
@@ -369,6 +373,28 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
         ctx.local_samdb.transaction_commit()
 
 
+    def join_finalise(ctx):
+        '''finalise the join, mark us synchronised and setup secrets db'''
+
+        print "Setting isSynchronized"
+        m = ldb.Message()
+        m.dn = ldb.Dn(ctx.samdb, '@ROOTDSE')
+        m["isSynchronized"] = ldb.MessageElement("TRUE", ldb.FLAG_MOD_REPLACE, "isSynchronized")
+        ctx.samdb.modify(m)
+
+        secrets_ldb = Ldb(ctx.paths.secrets, session_info=system_session(), lp=ctx.lp)
+
+        print "Setting up secrets database"
+        secretsdb_self_join(secrets_ldb, domain=ctx.domain_name,
+                            realm=ctx.realm,
+                            dnsdomain=ctx.dnsdomain,
+                            netbiosname=ctx.myname,
+                            domainsid=security.dom_sid(ctx.domsid),
+                            machinepass=ctx.acct_pass,
+                            secure_channel_type=misc.SEC_CHAN_RODC)
+
+
+
     # main join code
     ctx = join_ctx()
     ctx.creds = creds
@@ -413,7 +439,7 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
                              "<SID=%s>" % security.SID_BUILTIN_SERVER_OPERATORS,
                              "<SID=%s>" % security.SID_BUILTIN_BACKUP_OPERATORS,
                              "<SID=%s>" % security.SID_BUILTIN_ACCOUNT_OPERATORS ]
-    ctx.reveal_sid = "<SID=%s-571>" % ctx.domsid;
+    ctx.reveal_sid = "<SID=%s-%s>" % (ctx.domsid, security.DOMAIN_RID_RODC_ALLOW)
 
     ctx.dnsdomain = ldb.Dn(ctx.samdb, ctx.base_dn).canonical_str().split('/')[0]
     ctx.realm = ctx.dnsdomain
@@ -427,6 +453,7 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None,
         join_drs_connect(ctx)
         join_provision(ctx)
         join_replicate(ctx)
+        join_finalise(ctx)
     except:
         print "Join failed - cleaning up"
         cleanup_old_join(ctx)
diff --git a/source4/scripting/python/samba/tests/dcerpc/rpc_talloc.py b/source4/scripting/python/samba/tests/dcerpc/rpc_talloc.py
new file mode 100755
index 0000000..7a1ddb5
--- /dev/null
+++ b/source4/scripting/python/samba/tests/dcerpc/rpc_talloc.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# test generated python code from pidl
+
+import sys
+
+sys.path.insert(0, "bin/python")
+
+import samba
+from samba.dcerpc import drsuapi
+
+samba.talloc_enable_null_tracking()
+initial_blocks = samba.talloc_total_blocks(None)
+
+def check_blocks(object, num_expected):
+    nblocks = samba.talloc_total_blocks(object)
+    if object is None:
+        nblocks -= initial_blocks
+    if nblocks != num_expected:
+        raise Exception("Expected %u blocks in %s - got %u" % (num_expected, str(object), nblocks))
+
+check_blocks(None, 0)
+
+def get_rodc_partial_attribute_set():
+    '''get a list of attributes for RODC replication'''
+    partial_attribute_set = drsuapi.DsPartialAttributeSet()
+
+    # we expect one block for the object, and one for the structure
+    check_blocks(partial_attribute_set, 2)
+
+    attids = [ 1, 2, 3]
+    partial_attribute_set.version = 1
+    partial_attribute_set.attids     = attids
+    partial_attribute_set.num_attids = len(attids)
+
+    # we expect one block object, a structure, an ARRAY, and a reference to the array
+    check_blocks(partial_attribute_set, 4)
+
+    return partial_attribute_set
+
+def test_fun():
+    pas = get_rodc_partial_attribute_set()
+    check_blocks(pas, 4)
+    req8 = drsuapi.DsGetNCChangesRequest8()
+    check_blocks(req8, 2)
+    check_blocks(None, 6)
+    req8.partial_attribute_set = pas
+    if req8.partial_attribute_set.attids[1] != 2:
+        raise Exception("Wrong value in attids[2]")
+    # we now get an additional reference
+    samba.talloc_report_full(None)
+    check_blocks(None, 7)
+
+test_fun()


-- 
Samba Shared Repository


More information about the samba-cvs mailing list