diff options
author | Stefan Metzmacher <metze@samba.org> | 2018-11-29 12:41:34 +0100 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2019-01-12 03:13:41 +0100 |
commit | 8bd0f4405a3545437a9b52adff775696b542e1bf (patch) | |
tree | acec8660bb1e1c13c97011d5feb5a47af802315d /source4/librpc | |
parent | ae467704f3fe6794f1f4e31b1d5c4fd3f1a14053 (diff) | |
download | samba-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/librpc')
-rw-r--r-- | source4/librpc/rpc/pyrpc.c | 101 | ||||
-rw-r--r-- | source4/librpc/rpc/pyrpc_util.c | 29 | ||||
-rw-r--r-- | source4/librpc/rpc/pyrpc_util.h | 3 |
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__ */ |