summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2018-11-29 12:41:34 +0100
committerJeremy Allison <jra@samba.org>2019-01-12 03:13:41 +0100
commit8bd0f4405a3545437a9b52adff775696b542e1bf (patch)
treeacec8660bb1e1c13c97011d5feb5a47af802315d /source4
parentae467704f3fe6794f1f4e31b1d5c4fd3f1a14053 (diff)
downloadsamba-8bd0f4405a3545437a9b52adff775696b542e1bf.tar.gz
s4:pyrpc: add py_dcerpc_ndr_pointer_deref/wrap() infrastructure
Some idl files use more than one layer of unique pointers. e.g. NTSTATUS lsa_GetUserName( [in,unique] [string,charset(UTF16)] uint16 *system_name, [in,out,ref] lsa_String **account_name, [in,out,unique] lsa_String **authority_name ); In order to specify *io.in.authority_name = NULL, we need to wrap the pointer value (lsa_String or None) into an base.ndr_pointer() object. BUG: https://bugzilla.samba.org/show_bug.cgi?id=7113 BUG: https://bugzilla.samba.org/show_bug.cgi?id=11892 Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source4')
-rw-r--r--source4/librpc/rpc/pyrpc.c101
-rw-r--r--source4/librpc/rpc/pyrpc_util.c29
-rw-r--r--source4/librpc/rpc/pyrpc_util.h3
3 files changed, 133 insertions, 0 deletions
diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c
index e86ea0e94aa..cf2d4c24007 100644
--- a/source4/librpc/rpc/pyrpc.c
+++ b/source4/librpc/rpc/pyrpc.c
@@ -33,6 +33,8 @@ void initbase(void);
static PyTypeObject dcerpc_InterfaceType;
+static PyTypeObject *BaseObject_Type;
+
static PyTypeObject *ndr_syntax_id_Type;
static bool PyString_AsGUID(PyObject *object, struct GUID *uuid)
@@ -430,6 +432,88 @@ static PyTypeObject py_bind_time_features_syntax_SyntaxType = {
.tp_new = py_bind_time_features_syntax_new,
};
+struct py_dcerpc_ndr_pointer {
+ PyObject *value;
+};
+
+static void py_dcerpc_ndr_pointer_dealloc(PyObject* self)
+{
+ struct py_dcerpc_ndr_pointer *obj =
+ pytalloc_get_type(self, struct py_dcerpc_ndr_pointer);
+
+ Py_DECREF(obj->value);
+ obj->value = NULL;
+
+ self->ob_type->tp_free(self);
+}
+
+static PyObject *py_dcerpc_ndr_pointer_get_value(PyObject *self, void *closure)
+{
+ struct py_dcerpc_ndr_pointer *obj =
+ pytalloc_get_type(self, struct py_dcerpc_ndr_pointer);
+
+ Py_INCREF(obj->value);
+ return obj->value;
+}
+
+static int py_dcerpc_ndr_pointer_set_value(PyObject *self, PyObject *value, void *closure)
+{
+ struct py_dcerpc_ndr_pointer *obj =
+ pytalloc_get_type(self, struct py_dcerpc_ndr_pointer);
+
+ Py_DECREF(obj->value);
+ obj->value = value;
+ Py_INCREF(obj->value);
+ return 0;
+}
+
+static PyGetSetDef py_dcerpc_ndr_pointer_getsetters[] = {
+ { discard_const_p(char, "value"),
+ py_dcerpc_ndr_pointer_get_value,
+ py_dcerpc_ndr_pointer_set_value,
+ discard_const_p(char, "the value store by the pointer") },
+ { NULL }
+};
+
+static PyObject *py_dcerpc_ndr_pointer_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ PyObject *ret = NULL;
+ struct py_dcerpc_ndr_pointer *obj = NULL;
+ const char *kwnames[] = { "value", NULL };
+ PyObject *value = NULL;
+ bool ok;
+
+ ok = PyArg_ParseTupleAndKeywords(args, kwargs, "O:value",
+ discard_const_p(char *, kwnames),
+ &value);
+ if (!ok) {
+ return NULL;
+ }
+
+ ret = pytalloc_new(struct py_dcerpc_ndr_pointer, type);
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ obj = pytalloc_get_type(ret, struct py_dcerpc_ndr_pointer);
+ *obj = (struct py_dcerpc_ndr_pointer) {
+ .value = value,
+ };
+
+ Py_INCREF(obj->value);
+ return ret;
+}
+
+static PyTypeObject py_dcerpc_ndr_pointer_type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "base.ndr_pointer",
+ .tp_dealloc = py_dcerpc_ndr_pointer_dealloc,
+ .tp_getset = py_dcerpc_ndr_pointer_getsetters,
+ .tp_doc = "ndr_pointer(value)\n",
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_new = py_dcerpc_ndr_pointer_new,
+};
+
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
.m_name = "base",
@@ -440,8 +524,17 @@ static struct PyModuleDef moduledef = {
MODULE_INIT_FUNC(base)
{
PyObject *m;
+ PyObject *dep_talloc;
PyObject *dep_samba_dcerpc_misc;
+ dep_talloc = PyImport_ImportModule("talloc");
+ if (dep_talloc == NULL)
+ return NULL;
+
+ BaseObject_Type = (PyTypeObject *)PyObject_GetAttrString(dep_talloc, "BaseObject");
+ if (BaseObject_Type == NULL)
+ return NULL;
+
dep_samba_dcerpc_misc = PyImport_ImportModule("samba.dcerpc.misc");
if (dep_samba_dcerpc_misc == NULL)
return NULL;
@@ -457,6 +550,9 @@ MODULE_INIT_FUNC(base)
py_bind_time_features_syntax_SyntaxType.tp_base = ndr_syntax_id_Type;
py_bind_time_features_syntax_SyntaxType.tp_basicsize = pytalloc_BaseObject_size();
+ py_dcerpc_ndr_pointer_type.tp_base = BaseObject_Type;
+ py_dcerpc_ndr_pointer_type.tp_basicsize = pytalloc_BaseObject_size();
+
if (PyType_Ready(&dcerpc_InterfaceType) < 0)
return NULL;
@@ -467,6 +563,9 @@ MODULE_INIT_FUNC(base)
if (PyType_Ready(&py_bind_time_features_syntax_SyntaxType) < 0)
return NULL;
+ if (PyType_Ready(&py_dcerpc_ndr_pointer_type) < 0)
+ return NULL;
+
m = PyModule_Create(&moduledef);
if (m == NULL)
return NULL;
@@ -480,5 +579,7 @@ MODULE_INIT_FUNC(base)
PyModule_AddObject(m, "transfer_syntax_ndr64", (PyObject *)(void *)&py_transfer_syntax_ndr64_SyntaxType);
Py_INCREF((PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType);
PyModule_AddObject(m, "bind_time_features_syntax", (PyObject *)(void *)&py_bind_time_features_syntax_SyntaxType);
+ Py_INCREF((PyObject *)(void *)&py_dcerpc_ndr_pointer_type);
+ PyModule_AddObject(m, "ndr_pointer", (PyObject *)(void *)&py_dcerpc_ndr_pointer_type);
return m;
}
diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c
index cc67dfcdc3f..3a151e1591f 100644
--- a/source4/librpc/rpc/pyrpc_util.c
+++ b/source4/librpc/rpc/pyrpc_util.c
@@ -448,3 +448,32 @@ void *pyrpc_export_union(PyTypeObject *type, TALLOC_CTX *mem_ctx, int level,
Py_XDECREF(ret_obj);
return ret;
}
+
+PyObject *py_dcerpc_ndr_pointer_deref(PyTypeObject *type, PyObject *obj)
+{
+ if (!PyObject_TypeCheck(obj, type)) {
+ PyErr_Format(PyExc_TypeError,
+ "Expected type '%s' but got type '%s'",
+ (type)->tp_name, Py_TYPE(obj)->tp_name);
+ return NULL;
+ }
+
+ 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_obj = PyObject_Call((PyObject *)type, args, NULL);
+ Py_XDECREF(args);
+ return ret_obj;
+}
diff --git a/source4/librpc/rpc/pyrpc_util.h b/source4/librpc/rpc/pyrpc_util.h
index 12733122bb1..5a5f14de285 100644
--- a/source4/librpc/rpc/pyrpc_util.h
+++ b/source4/librpc/rpc/pyrpc_util.h
@@ -64,4 +64,7 @@ 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);
+PyObject *py_dcerpc_ndr_pointer_deref(PyTypeObject *type, PyObject *obj);
+PyObject *py_dcerpc_ndr_pointer_wrap(PyTypeObject *type, PyObject *obj);
+
#endif /* __PYRPC_UTIL_H__ */