[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Mon Feb 17 13:40:03 MST 2014


The branch, master has been updated
       via  bf1e65c s4:pyrpc: let dcerpc_interface_new() use py_dcerpc_interface_init_helper()
       via  4f31b3d s4:pyrpc: fix talloc hierachy in py_dcerpc_interface_init_helper()
      from  001b958 tdb: always open internal databases with incompatible hash.

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


- Log -----------------------------------------------------------------
commit bf1e65ceb83b8bceea79c6522f867e0c3644f70f
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Feb 15 10:19:29 2014 +0100

    s4:pyrpc: let dcerpc_interface_new() use py_dcerpc_interface_init_helper()
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>
    
    Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date(master): Mon Feb 17 21:39:30 CET 2014 on sn-devel-104

commit 4f31b3db3594f71cb86bf4c1cf4ae62886068962
Author: Stefan Metzmacher <metze at samba.org>
Date:   Sat Feb 15 10:12:04 2014 +0100

    s4:pyrpc: fix talloc hierachy in py_dcerpc_interface_init_helper()
    
    The tevent_context is cached under the connection,
    so we need to make sure it stays arround as long as the connection.
    
    Otherwise it will segfault while dereferencing the tevent_context
    on deallocation if a secondary connection is arround.
    
    This completes commit 4cc3388c034fa43c855fba802a30bbd2e78122be,
    which only fixed it in dcerpc_interface_new().
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

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

Summary of changes:
 source4/librpc/rpc/pyrpc.c      |  100 +++++++++--------------------------
 source4/librpc/rpc/pyrpc_util.c |  111 ++++++++++++++++++++++++++------------
 2 files changed, 102 insertions(+), 109 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c
index 0de3681..140d86c 100644
--- a/source4/librpc/rpc/pyrpc.c
+++ b/source4/librpc/rpc/pyrpc.c
@@ -296,7 +296,7 @@ static void dcerpc_interface_dealloc(PyObject* self)
 
 static PyObject *dcerpc_interface_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
 {
-	dcerpc_InterfaceObject *ret;
+	PyObject *ret;
 	const char *binding_string = NULL;
 	PyObject *py_lp_ctx = Py_None;
 	PyObject *py_credentials = Py_None;
@@ -305,97 +305,49 @@ static PyObject *dcerpc_interface_new(PyTypeObject *type, PyObject *args, PyObje
 	const char *kwnames[] = {
 		"binding", "syntax", "lp_ctx", "credentials", "basis_connection", NULL
 	};
-	struct ndr_interface_table *table;
-	NTSTATUS status;
+	static struct ndr_interface_table dummy_table;
+	PyObject *args2 = Py_None;
+	PyObject *kwargs2 = Py_None;
 
 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|OOO:connect", discard_const_p(char *, kwnames), &binding_string, &syntax, &py_lp_ctx, &py_credentials, &py_basis)) {
 		return NULL;
 	}
 
-	ret = PyObject_New(dcerpc_InterfaceObject, type);
-	ret->pipe = NULL;
-	ret->binding_handle = NULL;
-	ret->mem_ctx = talloc_new(NULL);
-	if (ret->mem_ctx == NULL) {
-		PyErr_NoMemory();
+	if (strncmp(binding_string, "irpc:", 5) == 0) {
+		PyErr_SetString(PyExc_ValueError, "irpc: transport not supported");
 		return NULL;
 	}
 
-	/* Create a dummy interface table struct. TODO: In the future, we should
+	/*
+	 * Fill a dummy interface table struct. TODO: In the future, we should
 	 * rather just allow connecting without requiring an interface table.
+	 *
+	 * We just fill the syntax during the connect, but keep the memory valid
+	 * the whole time.
 	 */
-
-	table = talloc_zero(ret->mem_ctx, struct ndr_interface_table);
-
-	if (table == NULL) {
-		PyErr_SetString(PyExc_MemoryError, "Allocating interface table");
-		TALLOC_FREE(ret->mem_ctx);
+	if (!ndr_syntax_from_py_object(syntax, &dummy_table.syntax_id)) {
 		return NULL;
 	}
 
-	if (!ndr_syntax_from_py_object(syntax, &table->syntax_id)) {
-		TALLOC_FREE(ret->mem_ctx);
+	args2 = Py_BuildValue("(s)", binding_string);
+	if (args2 == NULL) {
 		return NULL;
 	}
 
-	if (py_basis != Py_None) {
-		struct dcerpc_pipe *base_pipe;
-
-		if (!PyObject_TypeCheck(py_basis, &dcerpc_InterfaceType)) {
-			PyErr_SetString(PyExc_ValueError, "basis_connection must be a DCE/RPC connection");
-			TALLOC_FREE(ret->mem_ctx);
-			return NULL;
-		}
-
-		base_pipe = talloc_reference(ret->mem_ctx, 
-					 ((dcerpc_InterfaceObject *)py_basis)->pipe);
-
-		status = dcerpc_secondary_context(base_pipe, &ret->pipe, table);
-
-		ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe);
-	} else {
-		struct tevent_context *event_ctx;
-		struct loadparm_context *lp_ctx;
-		struct cli_credentials *credentials;
-
-		event_ctx = s4_event_context_init(ret->mem_ctx);
-		if (event_ctx == NULL) {
-			PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
-			TALLOC_FREE(ret->mem_ctx);
-			return NULL;
-		}
-
-		lp_ctx = lpcfg_from_py_object(event_ctx, py_lp_ctx);
-		if (lp_ctx == NULL) {
-			PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
-			TALLOC_FREE(ret->mem_ctx);
-			return NULL;
-		}
-
-		credentials = cli_credentials_from_py_object(py_credentials);
-		if (credentials == NULL) {
-			PyErr_SetString(PyExc_TypeError, "Expected credentials");
-			TALLOC_FREE(ret->mem_ctx);
-			return NULL;
-		}
-		status = dcerpc_pipe_connect(ret->mem_ctx, &ret->pipe, binding_string, 
-			     table, credentials, event_ctx, lp_ctx);
-
-		/*
-		 * the event context is cached under the connection,
-		 * so let it be a child of it.
-		 */
-		talloc_steal(ret->pipe->conn, event_ctx);
-	}
-
-	if (!NT_STATUS_IS_OK(status)) {
-		PyErr_SetDCERPCStatus(ret->pipe, status);
-		TALLOC_FREE(ret->mem_ctx);
+	kwargs2 = Py_BuildValue("{s:O,s:O,s:O}",
+				"lp_ctx", py_lp_ctx,
+				"credentials", py_credentials,
+				"basis_connection", py_basis);
+	if (kwargs2 == NULL) {
+		Py_DECREF(args2);
 		return NULL;
 	}
-	ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC;
-	ret->binding_handle = ret->pipe->binding_handle;
-	return (PyObject *)ret;
+
+	ret = py_dcerpc_interface_init_helper(type, args2, kwargs2, &dummy_table);
+	ZERO_STRUCT(dummy_table.syntax_id);
+	Py_DECREF(args2);
+	Py_DECREF(kwargs2);
+	return ret;
 }
 
 static PyTypeObject dcerpc_InterfaceType = {
diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c
index ab6caac..cec8574 100644
--- a/source4/librpc/rpc/pyrpc_util.c
+++ b/source4/librpc/rpc/pyrpc_util.c
@@ -91,13 +91,8 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
 {
 	dcerpc_InterfaceObject *ret;
 	const char *binding_string;
-	struct cli_credentials *credentials;
-	struct loadparm_context *lp_ctx = NULL;
 	PyObject *py_lp_ctx = Py_None, *py_credentials = Py_None, *py_basis = Py_None;
-	TALLOC_CTX *mem_ctx = NULL;
-	struct tevent_context *event_ctx;
 	NTSTATUS status;
-
 	const char *kwnames[] = {
 		"binding", "lp_ctx", "credentials", "basis_connection", NULL
 	};
@@ -106,35 +101,46 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
 		return NULL;
 	}
 
-	mem_ctx = talloc_new(NULL);
-	if (mem_ctx == NULL) {
-		PyErr_NoMemory();
-		return NULL;
-	}
-
-	lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx);
-	if (lp_ctx == NULL) {
-		PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
-		talloc_free(mem_ctx);
-		return NULL;
-	}
-
 	status = dcerpc_init();
 	if (!NT_STATUS_IS_OK(status)) {
 		PyErr_SetNTSTATUS(status);
-		talloc_free(mem_ctx);
 		return NULL;
 	}
 
 	ret = PyObject_New(dcerpc_InterfaceObject, type);
-	ret->mem_ctx = mem_ctx;
-
-	event_ctx = s4_event_context_init(ret->mem_ctx);
+	ret->pipe = NULL;
+	ret->binding_handle = NULL;
+	ret->mem_ctx = talloc_new(NULL);
+	if (ret->mem_ctx == NULL) {
+		PyErr_NoMemory();
+		return NULL;
+	}
 
 	if (strncmp(binding_string, "irpc:", 5) == 0) {
-		ret->pipe = NULL;
+		struct tevent_context *event_ctx;
+		struct loadparm_context *lp_ctx;
+
+		event_ctx = s4_event_context_init(ret->mem_ctx);
+		if (event_ctx == NULL) {
+			PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
+			TALLOC_FREE(ret->mem_ctx);
+			return NULL;
+		}
+
+		lp_ctx = lpcfg_from_py_object(event_ctx, py_lp_ctx);
+		if (lp_ctx == NULL) {
+			PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
+			TALLOC_FREE(ret->mem_ctx);
+			return NULL;
+		}
+
 		status = pyrpc_irpc_connect(ret->mem_ctx, binding_string+5, table,
 					    event_ctx, lp_ctx, &ret->binding_handle);
+		if (!NT_STATUS_IS_OK(status)) {
+			PyErr_SetNTSTATUS(status);
+			TALLOC_FREE(ret->mem_ctx);
+			return NULL;
+		}
 	} else if (py_basis != Py_None) {
 		struct dcerpc_pipe *base_pipe;
 		PyObject *py_base;
@@ -142,42 +148,77 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
 
 		py_base = PyImport_ImportModule("samba.dcerpc.base");
 		if (py_base == NULL) {
-			talloc_free(mem_ctx);
+			TALLOC_FREE(ret->mem_ctx);
 			return NULL;
 		}
 
 		ClientConnection_Type = (PyTypeObject *)PyObject_GetAttrString(py_base, "ClientConnection");
 		if (ClientConnection_Type == NULL) {
 			PyErr_SetNone(PyExc_TypeError);
-			talloc_free(mem_ctx);
+			TALLOC_FREE(ret->mem_ctx);
 			return NULL;
 		}
 
 		if (!PyObject_TypeCheck(py_basis, ClientConnection_Type)) {
 			PyErr_SetString(PyExc_TypeError, "basis_connection must be a DCE/RPC connection");
-			talloc_free(mem_ctx);
+			TALLOC_FREE(ret->mem_ctx);
 			return NULL;
 		}
 
-		base_pipe = talloc_reference(mem_ctx, ((dcerpc_InterfaceObject *)py_basis)->pipe);
+		base_pipe = talloc_reference(ret->mem_ctx,
+					 ((dcerpc_InterfaceObject *)py_basis)->pipe);
+		if (base_pipe == NULL) {
+			PyErr_NoMemory();
+			TALLOC_FREE(ret->mem_ctx);
+			return NULL;
+		}
 
 		status = dcerpc_secondary_context(base_pipe, &ret->pipe, table);
+		if (!NT_STATUS_IS_OK(status)) {
+			PyErr_SetNTSTATUS(status);
+			TALLOC_FREE(ret->mem_ctx);
+			return NULL;
+		}
 
 		ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe);
 	} else {
+		struct tevent_context *event_ctx;
+		struct loadparm_context *lp_ctx;
+		struct cli_credentials *credentials;
+
+		event_ctx = s4_event_context_init(ret->mem_ctx);
+		if (event_ctx == NULL) {
+			PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
+			TALLOC_FREE(ret->mem_ctx);
+			return NULL;
+		}
+
+		lp_ctx = lpcfg_from_py_object(event_ctx, py_lp_ctx);
+		if (lp_ctx == NULL) {
+			PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
+			TALLOC_FREE(ret->mem_ctx);
+			return NULL;
+		}
+
 		credentials = cli_credentials_from_py_object(py_credentials);
 		if (credentials == NULL) {
 			PyErr_SetString(PyExc_TypeError, "Expected credentials");
-			talloc_free(mem_ctx);
+			TALLOC_FREE(ret->mem_ctx);
 			return NULL;
 		}
-		status = dcerpc_pipe_connect(event_ctx, &ret->pipe, binding_string,
-		             table, credentials, event_ctx, lp_ctx);
-	}
-	if (NT_STATUS_IS_ERR(status)) {
-		PyErr_SetNTSTATUS(status);
-		talloc_free(mem_ctx);
-		return NULL;
+		status = dcerpc_pipe_connect(ret->mem_ctx, &ret->pipe, binding_string,
+			     table, credentials, event_ctx, lp_ctx);
+		if (!NT_STATUS_IS_OK(status)) {
+			PyErr_SetNTSTATUS(status);
+			TALLOC_FREE(ret->mem_ctx);
+			return NULL;
+		}
+
+		/*
+		 * the event context is cached under the connection,
+		 * so let it be a child of it.
+		 */
+		talloc_steal(ret->pipe->conn, event_ctx);
 	}
 
 	if (ret->pipe) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list