summaryrefslogtreecommitdiff
path: root/source4/librpc/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'source4/librpc/rpc')
-rw-r--r--source4/librpc/rpc/dcerpc.h1
-rw-r--r--source4/librpc/rpc/pyrpc.c69
-rw-r--r--source4/librpc/rpc/pyrpc.h18
3 files changed, 87 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..d8344be511 100644
--- a/source4/librpc/rpc/pyrpc.c
+++ b/source4/librpc/rpc/pyrpc.c
@@ -24,6 +24,74 @@
#include "librpc/rpc/dcerpc.h"
#include "lib/events/events.h"
+static PyObject *py_dcerpc_run_function(dcerpc_InterfaceObject *iface, struct PyNdrRpcMethodDef *md, PyObject *args, PyObject *kwargs)
+{
+ 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;
+}
+
+static PyObject *py_dcerpc_call_wrapper(PyObject *self, PyObject *args, void *wrapped, PyObject *kwargs)
+{
+ dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self;
+ struct PyNdrRpcMethodDef *md = wrapped;
+
+ return py_dcerpc_run_function(iface, md, args, kwargs);
+}
+
+
+bool PyInterface_AddNdrRpcMethods(PyTypeObject *ifacetype, const struct PyNdrRpcMethodDef *mds)
+{
+ int i;
+ for (i = 0; mds[i].name; i++) {
+ PyObject *ret;
+ struct wrapperbase *wb = calloc(sizeof(struct wrapperbase), 1);
+
+ wb->name = discard_const_p(char, mds[i].name);
+ wb->flags = PyWrapperFlag_KEYWORDS;
+ wb->wrapper = (wrapperfunc)py_dcerpc_call_wrapper;
+ wb->doc = discard_const_p(char, mds[i].doc);
+
+ ret = PyDescr_NewWrapper(ifacetype, wb, discard_const_p(void, &mds[i]));
+
+ PyDict_SetItemString(ifacetype->tp_dict, mds[i].name,
+ (PyObject *)ret);
+ }
+
+ return true;
+}
+
static bool PyString_AsGUID(PyObject *object, struct GUID *uuid)
{
NTSTATUS status;
@@ -311,7 +379,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;
}
diff --git a/source4/librpc/rpc/pyrpc.h b/source4/librpc/rpc/pyrpc.h
index 209d7d3f1f..af9ca728d8 100644
--- a/source4/librpc/rpc/pyrpc.h
+++ b/source4/librpc/rpc/pyrpc.h
@@ -21,6 +21,7 @@
#define _PYRPC_H_
#include "libcli/util/pyerrors.h"
+#include "librpc/rpc/dcerpc.h"
#define PY_CHECK_TYPE(type, var, fail) \
if (!type ## _Check(var)) {\
@@ -28,8 +29,10 @@
fail; \
}
+#define dom_sid0_Type dom_sid_Type
#define dom_sid2_Type dom_sid_Type
#define dom_sid28_Type dom_sid_Type
+#define dom_sid0_Check dom_sid_Check
#define dom_sid2_Check dom_sid_Check
#define dom_sid28_Check dom_sid_Check
@@ -52,4 +55,19 @@ 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, const struct PyNdrRpcMethodDef *mds);
+
#endif /* _PYRPC_H_ */