diff options
Diffstat (limited to 'source4/librpc')
-rw-r--r-- | source4/librpc/rpc/dcerpc.h | 1 | ||||
-rw-r--r-- | source4/librpc/rpc/pyrpc.c | 101 | ||||
-rw-r--r-- | source4/librpc/rpc/pyrpc.h | 16 |
3 files changed, 117 insertions, 1 deletions
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index ca6311a4fc..487f9f2eda 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -370,5 +370,6 @@ NTSTATUS dcerpc_request(struct dcerpc_pipe *p, DATA_BLOB *stub_data_in, DATA_BLOB *stub_data_out); +typedef NTSTATUS (*dcerpc_call_fn) (struct dcerpc_pipe *, TALLOC_CTX *, void *); #endif /* __DCERPC_H__ */ diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index 26242e8235..b04ca0be30 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -24,6 +24,103 @@ #include "librpc/rpc/dcerpc.h" #include "lib/events/events.h" +typedef struct dcerpc_FunctionObject { + PyObject_HEAD + struct PyNdrRpcMethodDef *method_def; +} dcerpc_FunctionObject; + +static PyMemberDef dcerpc_function_members[] = { + { discard_const_p(char, "__opnum__"), T_LONG, + offsetof(struct dcerpc_FunctionObject, method_def), 0, + discard_const_p(char, "opnum") }, + { NULL } +}; + + +static PyObject * dcerpc_function_ndr_pack_in(PyObject *self, PyObject *args, PyObject *kwargs) +{ + /* FIXME */ + return Py_None; +} + +static PyMethodDef dcerpc_function_methods[] = { + { "__ndr_pack_in__", (PyCFunction)dcerpc_function_ndr_pack_in, METH_VARARGS|METH_KEYWORDS, NULL }, + { NULL, NULL, 0, NULL }, +}; + +PyTypeObject dcerpc_FunctionType = { + PyObject_HEAD_INIT(NULL) 0, + .tp_name = "dcerpc.Function", + .tp_basicsize = sizeof(dcerpc_FunctionObject), + .tp_members = dcerpc_function_members, + .tp_methods = dcerpc_function_methods, + .tp_flags = Py_TPFLAGS_DEFAULT, +}; + +PyObject *py_dcerpc_call_wrapper(PyObject *self, PyObject *args, void *wrapped, PyObject *kwargs) +{ + dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self; + struct PyNdrRpcMethodDef *md = wrapped; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + void *r; + PyObject *result = Py_None; + + if (md->pack_in_data == NULL || md->unpack_out_data == NULL) { + PyErr_SetString(PyExc_NotImplementedError, "No marshalling code available yet"); + return NULL; + } + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) + return NULL; + + r = talloc_zero_size(mem_ctx, md->table->calls[md->opnum].struct_size); + if (r == NULL) + return NULL; + + if (!md->pack_in_data(args, kwargs, r)) { + talloc_free(mem_ctx); + return NULL; + } + + status = md->call(iface->pipe, mem_ctx, r); + if (NT_STATUS_IS_ERR(status)) { + PyErr_SetDCERPCStatus(iface->pipe, status); + talloc_free(mem_ctx); + return NULL; + } + + result = md->unpack_out_data(r); + + talloc_free(mem_ctx); + return result; +} + + +PyObject *PyDescr_NewNdrRpcMethod(PyTypeObject *ifacetype, struct PyNdrRpcMethodDef *md) +{ + struct wrapperbase *wb = calloc(sizeof(struct wrapperbase), 1); + + wb->name = md->name; + wb->flags = PyWrapperFlag_KEYWORDS; + wb->wrapper = py_dcerpc_call_wrapper; + wb->doc = md->doc; + + return PyDescr_NewWrapper(ifacetype, wb, md); +} + +bool PyInterface_AddNdrRpcMethods(PyTypeObject *ifacetype, struct PyNdrRpcMethodDef *mds) +{ + int i; + for (i = 0; mds[i].name; i++) { + PyDict_SetItemString(ifacetype->tp_dict, mds[i].name, + PyDescr_NewNdrRpcMethod(ifacetype, &mds[i])); + } + + return true; +} + static bool PyString_AsGUID(PyObject *object, struct GUID *uuid) { NTSTATUS status; @@ -311,7 +408,6 @@ static PyObject *dcerpc_interface_new(PyTypeObject *self, PyObject *args, PyObje talloc_free(mem_ctx); return NULL; } - ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC; return (PyObject *)ret; } @@ -341,6 +437,9 @@ void initbase(void) if (PyType_Ready(&dcerpc_InterfaceType) < 0) return; + if (PyType_Ready(&dcerpc_FunctionType) < 0) + return; + m = Py_InitModule3("base", NULL, "DCE/RPC protocol implementation"); if (m == NULL) return; diff --git a/source4/librpc/rpc/pyrpc.h b/source4/librpc/rpc/pyrpc.h index 209d7d3f1f..5ec9c6ed83 100644 --- a/source4/librpc/rpc/pyrpc.h +++ b/source4/librpc/rpc/pyrpc.h @@ -52,4 +52,20 @@ PyAPI_DATA(PyTypeObject) dcerpc_InterfaceType; void PyErr_SetDCERPCStatus(struct dcerpc_pipe *pipe, NTSTATUS status); +typedef bool (*py_data_pack_fn) (PyObject *args, PyObject *kwargs, void *r); +typedef PyObject *(*py_data_unpack_fn) (void *r); + +struct PyNdrRpcMethodDef { + const char *name; + const char *doc; + dcerpc_call_fn call; + py_data_pack_fn pack_in_data; + py_data_unpack_fn unpack_out_data; + uint32_t opnum; + const struct ndr_interface_table *table; +}; + +bool PyInterface_AddNdrRpcMethods(PyTypeObject *object, struct PyNdrRpcMethodDef *mds); +PyObject *PyDescr_NewNdrRpcMethod(PyTypeObject *type, struct PyNdrRpcMethodDef *md); + #endif /* _PYRPC_H_ */ |