Cleanup references to module objects returned from PyImport_ImportModule
[gd/samba-autobuild/.git] / source4 / librpc / rpc / pyrpc_util.c
index cfbb9cb19776a6c23d467aa52f2d6c8949d1dfd2..29fd281f54daddac19925730c4777318a3a07bc2 100644 (file)
@@ -21,6 +21,7 @@
 */
 
 #include <Python.h>
+#include "python/py3compat.h"
 #include "includes.h"
 #include "librpc/rpc/pyrpc_util.h"
 #include "librpc/rpc/dcerpc.h"
@@ -115,6 +116,11 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
        }
 
        ret = PyObject_New(dcerpc_InterfaceObject, type);
+       if (ret == NULL) {
+               PyErr_NoMemory();
+               return NULL;
+       }
+
        ret->pipe = NULL;
        ret->binding_handle = NULL;
        ret->mem_ctx = talloc_new(NULL);
@@ -131,6 +137,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (event_ctx == NULL) {
                        PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
                        return NULL;
                }
 
@@ -138,6 +145,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (lp_ctx == NULL) {
                        PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
                        return NULL;
                }
 
@@ -146,6 +154,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (!NT_STATUS_IS_OK(status)) {
                        PyErr_SetNTSTATUS(status);
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
                        return NULL;
                }
        } else if (py_basis != Py_None) {
@@ -156,6 +165,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                py_base = PyImport_ImportModule("samba.dcerpc.base");
                if (py_base == NULL) {
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
                        return NULL;
                }
 
@@ -163,12 +173,17 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (ClientConnection_Type == NULL) {
                        PyErr_SetNone(PyExc_TypeError);
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
+                       Py_DECREF(py_base);
                        return NULL;
                }
 
                if (!PyObject_TypeCheck(py_basis, ClientConnection_Type)) {
                        PyErr_SetString(PyExc_TypeError, "basis_connection must be a DCE/RPC connection");
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
+                       Py_DECREF(py_base);
+                       Py_DECREF(ClientConnection_Type);
                        return NULL;
                }
 
@@ -177,6 +192,9 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (base_pipe == NULL) {
                        PyErr_NoMemory();
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
+                       Py_DECREF(py_base);
+                       Py_DECREF(ClientConnection_Type);
                        return NULL;
                }
 
@@ -184,10 +202,15 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (!NT_STATUS_IS_OK(status)) {
                        PyErr_SetNTSTATUS(status);
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
+                       Py_DECREF(py_base);
+                       Py_DECREF(ClientConnection_Type);
                        return NULL;
                }
 
                ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe);
+               Py_XDECREF(ClientConnection_Type);
+               Py_XDECREF(py_base);
        } else {
                struct tevent_context *event_ctx;
                struct loadparm_context *lp_ctx;
@@ -197,6 +220,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (event_ctx == NULL) {
                        PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
                        return NULL;
                }
 
@@ -204,6 +228,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (lp_ctx == NULL) {
                        PyErr_SetString(PyExc_TypeError, "Expected loadparm context");
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
                        return NULL;
                }
 
@@ -211,6 +236,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (credentials == NULL) {
                        PyErr_SetString(PyExc_TypeError, "Expected credentials");
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
                        return NULL;
                }
                status = dcerpc_pipe_connect(ret->mem_ctx, &ret->pipe, binding_string,
@@ -218,6 +244,7 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py
                if (!NT_STATUS_IS_OK(status)) {
                        PyErr_SetNTSTATUS(status);
                        TALLOC_FREE(ret->mem_ctx);
+                       Py_DECREF(ret);
                        return NULL;
                }
 
@@ -333,7 +360,7 @@ PyObject *py_dcerpc_syntax_init_helper(PyTypeObject *type, PyObject *args, PyObj
                return NULL;
        }
 
-       obj = (struct ndr_syntax_id *)pytalloc_get_ptr(ret);
+       obj = pytalloc_get_type(ret, struct ndr_syntax_id);
        *obj = *syntax;
 
        return ret;
@@ -365,6 +392,7 @@ PyObject *py_return_ndr_struct(const char *module_name, const char *type_name,
 {
        PyTypeObject *py_type;
        PyObject *module;
+       PyObject *result = NULL;
 
        if (r == NULL) {
                Py_RETURN_NONE;
@@ -377,10 +405,14 @@ PyObject *py_return_ndr_struct(const char *module_name, const char *type_name,
 
        py_type = (PyTypeObject *)PyObject_GetAttrString(module, type_name);
        if (py_type == NULL) {
+               Py_DECREF(module);
                return NULL;
        }
 
-       return pytalloc_reference_ex(py_type, r_ctx, r);
+       result = pytalloc_reference_ex(py_type, r_ctx, r);
+       Py_CLEAR(module);
+       Py_CLEAR(py_type);
+       return result;
 }
 
 PyObject *PyString_FromStringOrNULL(const char *str)
@@ -388,27 +420,22 @@ PyObject *PyString_FromStringOrNULL(const char *str)
        if (str == NULL) {
                Py_RETURN_NONE;
        }
-       return PyString_FromString(str);
+       return PyStr_FromString(str);
 }
 
 PyObject *pyrpc_import_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
                             const void *in, const char *typename)
 {
-       static const char *mem_ctx_type = "TALLOC_CTX";
        PyObject *mem_ctx_obj = NULL;
        PyObject *in_obj = NULL;
        PyObject *ret = NULL;
 
-       mem_ctx_obj = PyCObject_FromVoidPtrAndDesc(mem_ctx,
-                                       discard_const_p(char, mem_ctx_type),
-                                       NULL);
+       mem_ctx_obj = pytalloc_GenericObject_reference(mem_ctx);
        if (mem_ctx_obj == NULL) {
                return NULL;
        }
 
-       in_obj = PyCObject_FromVoidPtrAndDesc(discard_const(in),
-                                       discard_const_p(char, typename),
-                                       NULL);
+       in_obj = pytalloc_GenericObject_reference_ex(mem_ctx, discard_const(in));
        if (in_obj == NULL) {
                Py_XDECREF(mem_ctx_obj);
                return NULL;
@@ -430,16 +457,11 @@ PyObject *pyrpc_import_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
 void *pyrpc_export_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
                         PyObject *in, const char *typename)
 {
-       static const char *mem_ctx_type = "TALLOC_CTX";
        PyObject *mem_ctx_obj = NULL;
        PyObject *ret_obj = NULL;
-       const char *ret_desc = NULL;
        void *ret = NULL;
-       int cmp;
 
-       mem_ctx_obj = PyCObject_FromVoidPtrAndDesc(mem_ctx,
-                                       discard_const_p(char, mem_ctx_type),
-                                       NULL);
+       mem_ctx_obj = pytalloc_GenericObject_reference(mem_ctx);
        if (mem_ctx_obj == NULL) {
                return NULL;
        }
@@ -453,33 +475,36 @@ void *pyrpc_export_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
                return NULL;
        }
 
-       if (!PyCObject_Check(ret_obj)) {
-               Py_XDECREF(ret_obj);
-               PyErr_Format(PyExc_TypeError,
-                            "New %s.__export__() returned no PyCObject!",
-                            type->tp_name);
-               return NULL;
-       }
+       ret = _pytalloc_get_type(ret_obj, typename);
+       Py_XDECREF(ret_obj);
+       return ret;
+}
 
-       ret_desc = (const char *)PyCObject_GetDesc(ret_obj);
-       if (ret_desc == NULL) {
-               Py_XDECREF(ret_obj);
+PyObject *py_dcerpc_ndr_pointer_deref(PyTypeObject *type, PyObject *obj)
+{
+       if (!PyObject_TypeCheck(obj, type)) {
                PyErr_Format(PyExc_TypeError,
-                            "New %s.__export__() returned no PyCObject_GetDesc()!",
-                            type->tp_name);
+                            "Expected type '%s' but got type '%s'",
+                            (type)->tp_name, Py_TYPE(obj)->tp_name);
                return NULL;
        }
 
-       cmp = strncmp(typename, ret_desc, strlen(typename) + 1);
-       if (cmp != 0) {
-               Py_XDECREF(ret_obj);
-               PyErr_Format(PyExc_TypeError,
-                            "New %s.__export__() returned PyCObject_GetDesc() != %s!",
-                            type->tp_name, typename);
+       return PyObject_GetAttrString(obj, discard_const_p(char, "value"));
+}
+
+PyObject *py_dcerpc_ndr_pointer_wrap(PyTypeObject *type, PyObject *obj)
+{
+       PyObject *args = NULL;
+       PyObject *ret_obj = NULL;
+
+       args = PyTuple_New(1);
+       if (args == NULL) {
                return NULL;
        }
+       Py_XINCREF(obj);
+       PyTuple_SetItem(args, 0, obj);
 
-       ret = PyCObject_AsVoidPtr(ret_obj);
-       Py_XDECREF(ret_obj);
-       return ret;
+       ret_obj = PyObject_Call((PyObject *)type, args, NULL);
+       Py_XDECREF(args);
+       return ret_obj;
 }