LCOV - code coverage report
Current view: top level - source4/librpc/rpc - pyrpc.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 175 259 67.6 %
Date: 2021-08-25 13:27:56 Functions: 18 22 81.8 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba utility functions
       4             :    Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include <Python.h>
      21             : #include "python/py3compat.h"
      22             : #include "includes.h"
      23             : #include "python/modules.h"
      24             : #include <structmember.h>
      25             : #include "librpc/rpc/pyrpc.h"
      26             : #include "lib/events/events.h"
      27             : #include "param/pyparam.h"
      28             : #include "librpc/rpc/dcerpc.h"
      29             : #include "librpc/rpc/pyrpc_util.h"
      30             : #include "auth/credentials/pycredentials.h"
      31             : #include "auth/gensec/gensec.h"
      32             : 
      33             : void initbase(void);
      34             : 
      35             : static PyTypeObject dcerpc_InterfaceType;
      36             : 
      37             : static PyTypeObject *BaseObject_Type;
      38             : 
      39             : static PyTypeObject *ndr_syntax_id_Type;
      40             : 
      41           6 : static bool PyString_AsGUID(PyObject *object, struct GUID *uuid)
      42             : {
      43             :         NTSTATUS status;
      44           6 :         status = GUID_from_string(PyUnicode_AsUTF8(object), uuid);
      45           6 :         if (NT_STATUS_IS_ERR(status)) {
      46           0 :                 PyErr_SetNTSTATUS(status);
      47           0 :                 return false;
      48             :         }
      49           6 :         return true;
      50             : }
      51             : 
      52           6 : static bool ndr_syntax_from_py_object(PyObject *object, struct ndr_syntax_id *syntax_id)
      53             : {
      54           6 :         ZERO_STRUCTP(syntax_id);
      55             : 
      56           6 :         if (PyUnicode_Check(object)) {
      57           0 :                 return PyString_AsGUID(object, &syntax_id->uuid);
      58           6 :         } else if (PyTuple_Check(object)) {
      59           6 :                 PyObject *item = NULL;
      60           6 :                 if (PyTuple_Size(object) < 1 || PyTuple_Size(object) > 2) {
      61           0 :                         PyErr_SetString(PyExc_ValueError, "Syntax ID tuple has invalid size");
      62           0 :                         return false;
      63             :                 }
      64             : 
      65           6 :                 item = PyTuple_GetItem(object, 0);
      66           6 :                 if (!PyUnicode_Check(item)) {
      67           0 :                         PyErr_SetString(PyExc_ValueError, "Expected GUID as first element in tuple");
      68           0 :                         return false;
      69             :                 }
      70             : 
      71           6 :                 if (!PyString_AsGUID(item, &syntax_id->uuid)) {
      72           0 :                         return false;
      73             :                 }
      74             : 
      75           6 :                 item = PyTuple_GetItem(object, 1);
      76           6 :                 if (!PyLong_Check(item)) {
      77           0 :                         PyErr_SetString(PyExc_ValueError, "Expected version as second element in tuple");
      78           0 :                         return false;
      79             :                 }
      80             : 
      81           6 :                 syntax_id->if_version = PyLong_AsLong(item);
      82           6 :                 return true;
      83             :         }
      84             : 
      85           0 :         PyErr_SetString(PyExc_TypeError, "Expected UUID or syntax id tuple");
      86           0 :         return false;
      87             : }
      88             : 
      89           1 : static PyObject *py_iface_server_name(PyObject *obj, void *closure)
      90             : {
      91             :         const char *server_name;
      92           1 :         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
      93             : 
      94           1 :         server_name = dcerpc_server_name(iface->pipe);
      95           1 :         if (server_name == NULL)
      96           1 :                 Py_RETURN_NONE;
      97             : 
      98           0 :         return PyUnicode_FromString(server_name);
      99             : }
     100             : 
     101           1 : static PyObject *py_ndr_syntax_id(struct ndr_syntax_id *syntax_id)
     102             : {
     103             :         PyObject *ret;
     104             :         char *uuid_str;
     105             : 
     106           1 :         uuid_str = GUID_string(NULL, &syntax_id->uuid);
     107           1 :         if (uuid_str == NULL)
     108           0 :                 return NULL;
     109             : 
     110           1 :         ret = Py_BuildValue("(s,i)", uuid_str, syntax_id->if_version);
     111             : 
     112           1 :         talloc_free(uuid_str);
     113             : 
     114           1 :         return ret;
     115             : }
     116             : 
     117           1 : static PyObject *py_iface_abstract_syntax(PyObject *obj, void *closure)
     118             : {
     119           1 :         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
     120             : 
     121           1 :         return py_ndr_syntax_id(&iface->pipe->syntax);
     122             : }
     123             : 
     124           0 : static PyObject *py_iface_transfer_syntax(PyObject *obj, void *closure)
     125             : {
     126           0 :         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
     127             : 
     128           0 :         return py_ndr_syntax_id(&iface->pipe->transfer_syntax);
     129             : }
     130             : 
     131          28 : static PyObject *py_iface_session_key(PyObject *obj, void *closure)
     132             : {
     133          28 :         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
     134             :         DATA_BLOB session_key;
     135             : 
     136          28 :         NTSTATUS status = dcerpc_fetch_session_key(iface->pipe, &session_key);
     137          28 :         PyErr_NTSTATUS_IS_ERR_RAISE(status);
     138             : 
     139          28 :         return PyBytes_FromStringAndSize((const char *)session_key.data, session_key.length);
     140             : }
     141             : 
     142           0 : static PyObject *py_iface_user_session_key(PyObject *obj, void *closure)
     143             : {
     144           0 :         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
     145             :         TALLOC_CTX *mem_ctx;
     146             :         NTSTATUS status;
     147           0 :         struct gensec_security *security = NULL;
     148           0 :         DATA_BLOB session_key = data_blob_null;
     149             :         static PyObject *session_key_obj = NULL;
     150             : 
     151           0 :         if (iface->pipe == NULL) {
     152           0 :                 PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY);
     153           0 :                 return NULL;
     154             :         }
     155             : 
     156           0 :         if (iface->pipe->conn == NULL) {
     157           0 :                 PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY);
     158           0 :                 return NULL;
     159             :         }
     160             : 
     161           0 :         if (iface->pipe->conn->security_state.generic_state == NULL) {
     162           0 :                 PyErr_SetNTSTATUS(NT_STATUS_NO_USER_SESSION_KEY);
     163           0 :                 return NULL;
     164             :         }
     165             : 
     166           0 :         security = iface->pipe->conn->security_state.generic_state;
     167             : 
     168           0 :         mem_ctx = talloc_new(NULL);
     169             : 
     170           0 :         status = gensec_session_key(security, mem_ctx, &session_key);
     171           0 :         if (!NT_STATUS_IS_OK(status)) {
     172           0 :                 talloc_free(mem_ctx);
     173           0 :                 PyErr_SetNTSTATUS(status);
     174           0 :                 return NULL;
     175             :         }
     176             : 
     177           0 :         session_key_obj = PyBytes_FromStringAndSize((const char *)session_key.data,
     178           0 :                                                      session_key.length);
     179           0 :         talloc_free(mem_ctx);
     180           0 :         return session_key_obj;
     181             : }
     182             : 
     183           0 : static PyObject *py_iface_get_timeout(PyObject *obj, void *closure)
     184             : {
     185           0 :         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
     186             :         uint32_t timeout;
     187             : 
     188           0 :         timeout = dcerpc_binding_handle_set_timeout(iface->binding_handle, 0);
     189           0 :         dcerpc_binding_handle_set_timeout(iface->binding_handle, timeout);
     190             : 
     191           0 :         return PyLong_FromUnsignedLong(timeout);
     192             : }
     193             : 
     194         922 : static int py_iface_set_timeout(PyObject *obj, PyObject *value, void *closure)
     195             : {
     196         922 :         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)obj;
     197             :         uint32_t timeout;
     198             : 
     199         922 :         timeout = PyLong_AsUnsignedLong(value);
     200         922 :         if (PyErr_Occurred() != NULL) {
     201           0 :                 return -1;
     202             :         }
     203             : 
     204         922 :         dcerpc_binding_handle_set_timeout(iface->binding_handle, timeout);
     205         922 :         return 0;
     206             : }
     207             : 
     208             : static PyGetSetDef dcerpc_interface_getsetters[] = {
     209             :         {
     210             :                 .name = discard_const_p(char, "server_name"),
     211             :                 .get  = py_iface_server_name,
     212             :                 .doc  = discard_const_p(char, "name of the server, if connected over SMB"),
     213             :         },
     214             :         {
     215             :                 .name = discard_const_p(char, "abstract_syntax"),
     216             :                 .get  = py_iface_abstract_syntax,
     217             :                 .doc  = discard_const_p(char, "syntax id of the abstract syntax"),
     218             :         },
     219             :         {
     220             :                 .name = discard_const_p(char, "transfer_syntax"),
     221             :                 .get  = py_iface_transfer_syntax,
     222             :                 .doc  = discard_const_p(char, "syntax id of the transfer syntax"),
     223             :         },
     224             :         {
     225             :                 .name = discard_const_p(char, "session_key"),
     226             :                 .get  = py_iface_session_key,
     227             :                 .doc  = discard_const_p(char, "session key (as used for blob encryption on LSA and SAMR)"),
     228             :         },
     229             :         {
     230             :                 .name = discard_const_p(char, "user_session_key"),
     231             :                 .get  = py_iface_user_session_key,
     232             :                 .doc  = discard_const_p(char, "user_session key (as used for blob encryption on DRSUAPI)"),
     233             :         },
     234             :         {
     235             :                 .name = discard_const_p(char, "request_timeout"),
     236             :                 .get  = py_iface_get_timeout,
     237             :                 .set  = py_iface_set_timeout,
     238             :                 .doc  = discard_const_p(char, "request timeout,    in seconds"),
     239             :         },
     240             :         { .name = NULL }
     241             : };
     242             : 
     243           7 : static PyObject *py_iface_request(PyObject *self, PyObject *args, PyObject *kwargs)
     244             : {
     245           7 :         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self;
     246             :         int opnum;
     247             :         DATA_BLOB data_in, data_out;
     248             :         NTSTATUS status;
     249             :         char *in_data;
     250             :         Py_ssize_t in_length;
     251             :         PyObject *ret;
     252           7 :         PyObject *object = NULL;
     253             :         struct GUID object_guid;
     254           7 :         TALLOC_CTX *mem_ctx = talloc_new(NULL);
     255           7 :         uint32_t out_flags = 0;
     256           7 :         const char *kwnames[] = { "opnum", "data", "object", NULL };
     257             : 
     258           7 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "is#|O:request", 
     259             :                 discard_const_p(char *, kwnames), &opnum, &in_data, &in_length, &object)) {
     260           0 :                 talloc_free(mem_ctx);
     261           0 :                 return NULL;
     262             :         }
     263             : 
     264           7 :         data_in.data = (uint8_t *)talloc_memdup(mem_ctx, in_data, in_length);
     265           7 :         data_in.length = in_length;
     266             : 
     267           7 :         ZERO_STRUCT(data_out);
     268             : 
     269           7 :         if (object != NULL && !PyString_AsGUID(object, &object_guid)) {
     270           0 :                 talloc_free(mem_ctx);
     271           0 :                 return NULL;
     272             :         }
     273             : 
     274          21 :         status = dcerpc_binding_handle_raw_call(iface->binding_handle,
     275           7 :                                                 object?&object_guid:NULL,
     276             :                                                 opnum,
     277             :                                                 0, /* in_flags */
     278           7 :                                                 data_in.data,
     279             :                                                 data_in.length,
     280             :                                                 mem_ctx,
     281             :                                                 &data_out.data,
     282             :                                                 &data_out.length,
     283             :                                                 &out_flags);
     284           7 :         if (!NT_STATUS_IS_OK(status)) {
     285           0 :                 PyErr_SetDCERPCStatus(iface->pipe, status);
     286           0 :                 talloc_free(mem_ctx);
     287           0 :                 return NULL;
     288             :         }
     289             : 
     290           7 :         ret = PyBytes_FromStringAndSize((char *)data_out.data, data_out.length);
     291             : 
     292           7 :         talloc_free(mem_ctx);
     293           7 :         return ret;
     294             : }
     295             : 
     296          28 : static PyObject *py_iface_transport_encrypted(PyObject *self)
     297             : {
     298          28 :         dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self;
     299             : 
     300          28 :         if (dcerpc_transport_encrypted(iface->pipe)) {
     301           2 :                 Py_RETURN_TRUE;
     302             :         }
     303             : 
     304          26 :         Py_RETURN_FALSE;
     305             : }
     306             : 
     307             : static PyMethodDef dcerpc_interface_methods[] = {
     308             :         { "request", PY_DISCARD_FUNC_SIG(PyCFunction, py_iface_request),
     309             :                 METH_VARARGS|METH_KEYWORDS,
     310             :                 "S.request(opnum, data, object=None) -> data\n"
     311             :                 "Make a raw request" },
     312             :         { "transport_encrypted", PY_DISCARD_FUNC_SIG(PyCFunction, py_iface_transport_encrypted),
     313             :                 METH_NOARGS,
     314             :                 "Check if the DCE transport is encrypted" },
     315             :         { NULL, NULL, 0, NULL },
     316             : };
     317             : 
     318        3794 : static void dcerpc_interface_dealloc(PyObject* self)
     319             : {
     320        3794 :         dcerpc_InterfaceObject *interface = (dcerpc_InterfaceObject *)self;
     321             : 
     322        3794 :         struct tevent_context *ev_save = talloc_reparent(
     323        3794 :                 interface->mem_ctx, NULL, interface->ev);
     324        3794 :         SMB_ASSERT(ev_save != NULL);
     325             : 
     326        3794 :         interface->binding_handle = NULL;
     327        3794 :         interface->pipe = NULL;
     328             : 
     329             :         /*
     330             :          * Free everything *except* the event context, which must go
     331             :          * away last
     332             :          */
     333        3794 :         TALLOC_FREE(interface->mem_ctx);
     334             : 
     335             :         /*
     336             :          * Now wish a fond goodbye to the event context itself
     337             :          */
     338        3794 :         talloc_unlink(NULL, ev_save);
     339        3794 :         self->ob_type->tp_free(self);
     340        3794 : }
     341             : 
     342           6 : static PyObject *dcerpc_interface_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     343             : {
     344             :         PyObject *ret;
     345           6 :         const char *binding_string = NULL;
     346           6 :         PyObject *py_lp_ctx = Py_None;
     347           6 :         PyObject *py_credentials = Py_None;
     348           6 :         PyObject *syntax = Py_None;
     349           6 :         PyObject *py_basis = Py_None;
     350           6 :         const char *kwnames[] = {
     351             :                 "binding", "syntax", "lp_ctx", "credentials", "basis_connection", NULL
     352             :         };
     353             :         static struct ndr_interface_table dummy_table;
     354             :         static struct ndr_interface_string_array dummy_endpoints;
     355           6 :         PyObject *args2 = Py_None;
     356           6 :         PyObject *kwargs2 = Py_None;
     357             : 
     358           6 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|OOO:connect", discard_const_p(char *, kwnames), &binding_string, &syntax, &py_lp_ctx, &py_credentials, &py_basis)) {
     359           0 :                 return NULL;
     360             :         }
     361             : 
     362           6 :         if (strncmp(binding_string, "irpc:", 5) == 0) {
     363           0 :                 PyErr_SetString(PyExc_ValueError, "irpc: transport not supported");
     364           0 :                 return NULL;
     365             :         }
     366             : 
     367             :         /*
     368             :          * Fill a dummy interface table struct. TODO: In the future, we should
     369             :          * rather just allow connecting without requiring an interface table.
     370             :          *
     371             :          * We just fill the syntax during the connect, but keep the memory valid
     372             :          * the whole time.
     373             :          */
     374           6 :         if (!ndr_syntax_from_py_object(syntax, &dummy_table.syntax_id)) {
     375           0 :                 return NULL;
     376             :         }
     377             : 
     378             :         /*
     379             :          * Initialise the endpoints list in dummy_table if required
     380             :          */
     381           6 :         if (dummy_table.endpoints == NULL) {
     382           1 :                 dummy_table.endpoints = &dummy_endpoints;
     383             :         }
     384             : 
     385           6 :         args2 = Py_BuildValue("(s)", binding_string);
     386           6 :         if (args2 == NULL) {
     387           0 :                 return NULL;
     388             :         }
     389             : 
     390           6 :         kwargs2 = Py_BuildValue("{s:O,s:O,s:O}",
     391             :                                 "lp_ctx", py_lp_ctx,
     392             :                                 "credentials", py_credentials,
     393             :                                 "basis_connection", py_basis);
     394           6 :         if (kwargs2 == NULL) {
     395           0 :                 Py_DECREF(args2);
     396           0 :                 return NULL;
     397             :         }
     398             : 
     399           6 :         ret = py_dcerpc_interface_init_helper(type, args2, kwargs2, &dummy_table);
     400           6 :         ZERO_STRUCT(dummy_table.syntax_id);
     401           6 :         Py_DECREF(args2);
     402           6 :         Py_DECREF(kwargs2);
     403           6 :         return ret;
     404             : }
     405             : 
     406             : static PyTypeObject dcerpc_InterfaceType = {
     407             :         PyVarObject_HEAD_INIT(NULL, 0)
     408             :         .tp_name = "dcerpc.ClientConnection",
     409             :         .tp_basicsize = sizeof(dcerpc_InterfaceObject),
     410             :         .tp_dealloc = dcerpc_interface_dealloc,
     411             :         .tp_getset = dcerpc_interface_getsetters,
     412             :         .tp_methods = dcerpc_interface_methods,
     413             :         .tp_doc = "ClientConnection(binding, syntax, lp_ctx=None, credentials=None) -> connection\n"
     414             : "\n"
     415             : "binding should be a DCE/RPC binding string (for example: ncacn_ip_tcp:127.0.0.1)\n"
     416             : "syntax should be a tuple with a GUID and version number of an interface\n"
     417             : "lp_ctx should be a path to a smb.conf file or a param.LoadParm object\n"
     418             : "credentials should be a credentials.Credentials object.\n\n",
     419             :         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     420             :         .tp_new = dcerpc_interface_new,
     421             : };
     422             : 
     423         483 : static PyObject *py_transfer_syntax_ndr_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     424             : {
     425         483 :         return py_dcerpc_syntax_init_helper(type, args, kwargs, &ndr_transfer_syntax_ndr);
     426             : }
     427             : 
     428             : static PyTypeObject py_transfer_syntax_ndr_SyntaxType = {
     429             :         PyVarObject_HEAD_INIT(NULL, 0)
     430             :         .tp_name = "base.transfer_syntax_ndr",
     431             :         .tp_doc = "transfer_syntax_ndr()\n",
     432             :         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     433             :         .tp_new = py_transfer_syntax_ndr_new,
     434             : };
     435             : 
     436          30 : static PyObject *py_transfer_syntax_ndr64_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     437             : {
     438          30 :         return py_dcerpc_syntax_init_helper(type, args, kwargs, &ndr_transfer_syntax_ndr64);
     439             : }
     440             : 
     441             : static PyTypeObject py_transfer_syntax_ndr64_SyntaxType = {
     442             :         PyVarObject_HEAD_INIT(NULL, 0)
     443             :         .tp_name = "base.transfer_syntax_ndr64",
     444             :         .tp_doc = "transfer_syntax_ndr64()\n",
     445             :         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     446             :         .tp_new = py_transfer_syntax_ndr64_new,
     447             : };
     448             : 
     449          36 : static PyObject *py_bind_time_features_syntax_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     450             : {
     451          36 :         const char *kwnames[] = {
     452             :                 "features", NULL
     453             :         };
     454          36 :         unsigned long long features = 0;
     455             :         struct ndr_syntax_id syntax;
     456          36 :         PyObject *args2 = Py_None;
     457          36 :         PyObject *kwargs2 = Py_None;
     458             : 
     459          36 :         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "K:features", discard_const_p(char *, kwnames), &features)) {
     460           0 :                 return NULL;
     461             :         }
     462             : 
     463          36 :         args2 = Py_BuildValue("()");
     464          36 :         if (args2 == NULL) {
     465           0 :                 return NULL;
     466             :         }
     467             : 
     468          36 :         kwargs2 = Py_BuildValue("{}");
     469          36 :         if (kwargs2 == NULL) {
     470           0 :                 Py_DECREF(args2);
     471           0 :                 return NULL;
     472             :         }
     473             : 
     474          36 :         syntax = dcerpc_construct_bind_time_features(features);
     475             : 
     476          36 :         return py_dcerpc_syntax_init_helper(type, args2, kwargs2, &syntax);
     477             : }
     478             : 
     479             : static PyTypeObject py_bind_time_features_syntax_SyntaxType = {
     480             :         PyVarObject_HEAD_INIT(NULL, 0)
     481             :         .tp_name = "base.bind_time_features_syntax",
     482             :         .tp_doc = "bind_time_features_syntax(features)\n",
     483             :         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     484             :         .tp_new = py_bind_time_features_syntax_new,
     485             : };
     486             : 
     487             : struct py_dcerpc_ndr_pointer {
     488             :         PyObject *value;
     489             : };
     490             : 
     491         325 : static void py_dcerpc_ndr_pointer_dealloc(PyObject* self)
     492             : {
     493         325 :         struct py_dcerpc_ndr_pointer *obj =
     494             :                 pytalloc_get_type(self, struct py_dcerpc_ndr_pointer);
     495             : 
     496         325 :         Py_DECREF(obj->value);
     497         325 :         obj->value = NULL;
     498             : 
     499         325 :         self->ob_type->tp_free(self);
     500         325 : }
     501             : 
     502         324 : static PyObject *py_dcerpc_ndr_pointer_get_value(PyObject *self, void *closure)
     503             : {
     504         324 :         struct py_dcerpc_ndr_pointer *obj =
     505             :                 pytalloc_get_type(self, struct py_dcerpc_ndr_pointer);
     506             : 
     507         324 :         Py_INCREF(obj->value);
     508         324 :         return obj->value;
     509             : }
     510             : 
     511           0 : static int py_dcerpc_ndr_pointer_set_value(PyObject *self, PyObject *value, void *closure)
     512             : {
     513           0 :         struct py_dcerpc_ndr_pointer *obj =
     514             :                 pytalloc_get_type(self, struct py_dcerpc_ndr_pointer);
     515             : 
     516           0 :         Py_DECREF(obj->value);
     517           0 :         obj->value = value;
     518           0 :         Py_INCREF(obj->value);
     519           0 :         return 0;
     520             : }
     521             : 
     522             : static PyGetSetDef py_dcerpc_ndr_pointer_getsetters[] = {
     523             :         {
     524             :                 .name = discard_const_p(char, "value"),
     525             :                 .get  = py_dcerpc_ndr_pointer_get_value,
     526             :                 .set  = py_dcerpc_ndr_pointer_set_value,
     527             :                 .doc  = discard_const_p(char, "the value store by the pointer"),
     528             :         },
     529             :         {
     530             :                 .name = NULL,
     531             :         },
     532             : };
     533             : 
     534         325 : static PyObject *py_dcerpc_ndr_pointer_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     535             : {
     536         325 :         PyObject *ret = NULL;
     537         325 :         struct py_dcerpc_ndr_pointer *obj = NULL;
     538         325 :         const char *kwnames[] = { "value", NULL };
     539         325 :         PyObject *value = NULL;
     540             :         bool ok;
     541             : 
     542         325 :         ok = PyArg_ParseTupleAndKeywords(args, kwargs, "O:value",
     543             :                                          discard_const_p(char *, kwnames),
     544             :                                          &value);
     545         325 :         if (!ok) {
     546           0 :                 return NULL;
     547             :         }
     548             : 
     549         325 :         ret = pytalloc_new(struct py_dcerpc_ndr_pointer, type);
     550         325 :         if (ret == NULL) {
     551           0 :                 return NULL;
     552             :         }
     553             : 
     554         325 :         obj = pytalloc_get_type(ret, struct py_dcerpc_ndr_pointer);
     555         325 :         *obj = (struct py_dcerpc_ndr_pointer) {
     556             :                 .value = value,
     557             :         };
     558             : 
     559         325 :         Py_INCREF(obj->value);
     560         325 :         return ret;
     561             : }
     562             : 
     563             : static PyTypeObject py_dcerpc_ndr_pointer_type = {
     564             :         PyVarObject_HEAD_INIT(NULL, 0)
     565             :         .tp_name = "base.ndr_pointer",
     566             :         .tp_dealloc = py_dcerpc_ndr_pointer_dealloc,
     567             :         .tp_getset = py_dcerpc_ndr_pointer_getsetters,
     568             :         .tp_doc = "ndr_pointer(value)\n",
     569             :         .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
     570             :         .tp_new = py_dcerpc_ndr_pointer_new,
     571             : };
     572             : 
     573             : static struct PyModuleDef moduledef = {
     574             :     PyModuleDef_HEAD_INIT,
     575             :     .m_name = "base",
     576             :     .m_doc = "DCE/RPC protocol implementation",
     577             :     .m_size = -1,
     578             : };
     579             : 
     580        4966 : MODULE_INIT_FUNC(base)
     581             : {
     582             :         PyObject *m;
     583             :         PyObject *dep_talloc;
     584             :         PyObject *dep_samba_dcerpc_misc;
     585             : 
     586        4966 :         dep_talloc = PyImport_ImportModule("talloc");
     587        4966 :         if (dep_talloc == NULL)
     588           0 :                 return NULL;
     589             : 
     590        4966 :         BaseObject_Type = (PyTypeObject *)PyObject_GetAttrString(dep_talloc, "BaseObject");
     591        4966 :         if (BaseObject_Type == NULL) {
     592           0 :                 Py_CLEAR(dep_talloc);
     593           0 :                 return NULL;
     594             :         }
     595             : 
     596        4966 :         Py_CLEAR(dep_talloc);
     597        4966 :         dep_samba_dcerpc_misc = PyImport_ImportModule("samba.dcerpc.misc");
     598        4966 :         if (dep_samba_dcerpc_misc == NULL) {
     599           0 :                 return NULL;
     600             :         }
     601             : 
     602        4966 :         ndr_syntax_id_Type = (PyTypeObject *)PyObject_GetAttrString(dep_samba_dcerpc_misc, "ndr_syntax_id");
     603        4966 :         Py_CLEAR(dep_samba_dcerpc_misc);
     604        4966 :         if (ndr_syntax_id_Type == NULL) {
     605           0 :                 return NULL;
     606             :         }
     607             : 
     608        4966 :         py_transfer_syntax_ndr_SyntaxType.tp_base = ndr_syntax_id_Type;
     609        4966 :         py_transfer_syntax_ndr_SyntaxType.tp_basicsize = pytalloc_BaseObject_size();
     610        4966 :         py_transfer_syntax_ndr64_SyntaxType.tp_base = ndr_syntax_id_Type;
     611        4966 :         py_transfer_syntax_ndr64_SyntaxType.tp_basicsize = pytalloc_BaseObject_size();
     612        4966 :         py_bind_time_features_syntax_SyntaxType.tp_base = ndr_syntax_id_Type;
     613        4966 :         py_bind_time_features_syntax_SyntaxType.tp_basicsize = pytalloc_BaseObject_size();
     614             : 
     615        4966 :         py_dcerpc_ndr_pointer_type.tp_base = BaseObject_Type;
     616        4966 :         py_dcerpc_ndr_pointer_type.tp_basicsize = pytalloc_BaseObject_size();
     617             : 
     618        4966 :         if (PyType_Ready(&dcerpc_InterfaceType) < 0) {
     619           0 :                 return NULL;
     620             :         }
     621             : 
     622        4966 :         if (PyType_Ready(&py_transfer_syntax_ndr_SyntaxType) < 0) {
     623           0 :                 return NULL;
     624             :         }
     625        4966 :         if (PyType_Ready(&py_transfer_syntax_ndr64_SyntaxType) < 0) {
     626           0 :                 return NULL;
     627             :         }
     628        4966 :         if (PyType_Ready(&py_bind_time_features_syntax_SyntaxType) < 0) {
     629           0 :                 return NULL;
     630             :         }
     631             : 
     632        4966 :         if (PyType_Ready(&py_dcerpc_ndr_pointer_type) < 0) {
     633           0 :                 return NULL;
     634             :         }
     635             : 
     636        4966 :         m = PyModule_Create(&moduledef);
     637        4966 :         if (m == NULL) {
     638           0 :                 return NULL;
     639             :         }
     640             : 
     641        4966 :         Py_INCREF((PyObject *)&dcerpc_InterfaceType);
     642        4966 :         PyModule_AddObject(m, "ClientConnection", (PyObject *)&dcerpc_InterfaceType);
     643             : 
     644        4966 :         Py_INCREF((PyObject *)(void *)&py_transfer_syntax_ndr_SyntaxType);
     645        4966 :         PyModule_AddObject(m, "transfer_syntax_ndr", (PyObject *)(void *)&py_transfer_syntax_ndr_SyntaxType);
     646        4966 :         Py_INCREF((PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType);
     647        4966 :         PyModule_AddObject(m, "transfer_syntax_ndr64", (PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType);
     648        4966 :         Py_INCREF((PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType);
     649        4966 :         PyModule_AddObject(m, "bind_time_features_syntax", (PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType);
     650        4966 :         Py_INCREF((PyObject *)(void *)&py_dcerpc_ndr_pointer_type);
     651        4966 :         PyModule_AddObject(m, "ndr_pointer", (PyObject *)(void *)&py_dcerpc_ndr_pointer_type);
     652        4966 :         return m;
     653             : }

Generated by: LCOV version 1.13