+ s->chunk.gensec_skey = &s->gensec_skey;
+ s->chunk.partition = &s->partition;
+ s->chunk.forest = &s->forest;
+ s->chunk.dest_dsa = &s->dest_dsa;
+
+ return PyCObject_FromTallocPtr(s);
+}
+
+
+/*
+ process one replication chunk
+ */
+static PyObject *py_net_replicate_chunk(py_net_Object *self, PyObject *args, PyObject *kwargs)
+{
+ const char *kwnames[] = { "state", "level", "ctr", "schema", NULL };
+ PyObject *py_state, *py_ctr, *py_schema;
+ struct replicate_state *s;
+ unsigned level;
+ NTSTATUS (*chunk_handler)(void *private_data, const struct libnet_BecomeDC_StoreChunk *c);
+ NTSTATUS status;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OIO|O",
+ discard_const_p(char *, kwnames),
+ &py_state, &level, &py_ctr, &py_schema)) {
+ return NULL;
+ }
+
+ s = talloc_get_type(PyCObject_AsVoidPtr(py_state), struct replicate_state);
+ if (!s) {
+ PyErr_SetString(PyExc_TypeError, "Expected replication_state");
+ return NULL;
+ }
+
+ switch (level) {
+ case 1:
+ if (strcmp("drsuapi.DsGetNCChangesCtr1", Py_TYPE(py_ctr)->tp_name) != 0) {
+ PyErr_SetString(PyExc_TypeError, "Expected DsGetNCChangesCtr1 type for ctr");
+ return NULL;
+ }
+ 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;
+ s->partition.source_dsa_guid = s->chunk.ctr1->source_dsa_guid;
+ s->partition.source_dsa_invocation_id = s->chunk.ctr1->source_dsa_invocation_id;
+ s->partition.highwatermark = s->chunk.ctr1->new_highwatermark;
+ break;
+ case 6:
+ if (strcmp("drsuapi.DsGetNCChangesCtr6", Py_TYPE(py_ctr)->tp_name) != 0) {
+ PyErr_SetString(PyExc_TypeError, "Expected DsGetNCChangesCtr6 type for ctr");
+ return NULL;
+ }
+ 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;
+ s->partition.source_dsa_guid = s->chunk.ctr6->source_dsa_guid;
+ s->partition.source_dsa_invocation_id = s->chunk.ctr6->source_dsa_invocation_id;
+ s->partition.highwatermark = s->chunk.ctr6->new_highwatermark;
+ break;
+ default:
+ PyErr_Format(PyExc_TypeError, "Bad level %u in replicate_chunk", level);
+ return NULL;
+ }
+
+ chunk_handler = libnet_vampire_cb_store_chunk;
+ if (py_schema) {
+ if (!PyBool_Check(py_schema)) {
+ PyErr_SetString(PyExc_TypeError, "Expected boolean schema");
+ return NULL;
+ }
+ if (py_schema == Py_True) {
+ chunk_handler = libnet_vampire_cb_schema_chunk;
+ }
+ }
+
+ s->chunk.ctr_level = level;
+
+ status = chunk_handler(s->vampire_state, &s->chunk);
+ if (!NT_STATUS_IS_OK(status)) {
+ PyErr_Format(PyExc_TypeError, "Failed to process chunk: %s", nt_errstr(status));
+ return NULL;
+ }