summaryrefslogtreecommitdiff
path: root/source4/librpc
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2008-05-25 23:14:48 +0200
committerJelmer Vernooij <jelmer@samba.org>2008-05-25 23:14:48 +0200
commit77acb789e2ea5eca3b0602e6397df76c5af55efe (patch)
tree8d889b516a44e39b0a9f9862cf87959f0167eda3 /source4/librpc
parent01fd6886466f1976d30b4deba4fe224344f760c2 (diff)
downloadsamba-77acb789e2ea5eca3b0602e6397df76c5af55efe.tar.gz
samba-77acb789e2ea5eca3b0602e6397df76c5af55efe.tar.bz2
samba-77acb789e2ea5eca3b0602e6397df76c5af55efe.zip
Trim the size of the Python bindings a bit.
(This used to be commit 717ce0b640a5c3aa62804b9869ef4dcc0f71b7ba)
Diffstat (limited to 'source4/librpc')
-rw-r--r--source4/librpc/rpc/dcerpc.h1
-rw-r--r--source4/librpc/rpc/pyrpc.c101
-rw-r--r--source4/librpc/rpc/pyrpc.h16
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_ */